[PASCAL] modul DOS, proc. RMDIR - ioresult nie dziala


(Przemekbaranowski) #1

Witam!

Napisalem w pascalu poniższą procedurę:

procedure usunkatalog;

var

 a,b,c:string;

begin

clrscr;

gotoxy(20,12);

textcolor(14);

write('Podaj nazwe katalogu do usuniecia:');

gotoxy(20,13);

textcolor(7);

writeln('katalog zostanie usuniety z bierzacego katalogu');

gotoxy(22,14);

textcolor(white);

 myreadlnstr(a);

 getdir(0,b);

 c:=b+'/'+a;

  {$I-}rmdir(c); {$I+}

  gotoxy(20,16);

  textcolor(green);

  if ioresult = 0 then write('Katalog usunieto');

  textcolor(red);

  if ioresult <> 0 then write ('Nie usunieto katalogu');

  gotoxy(28,24);

  textcolor(15);

  write('Press ENTER to continue');

  readln(b);

end;

Nie wiem dlaczego, ale jest problem ze zwracaniem ioresult. Jeżeli katalog przeznaczony do usunięcia jest pusty, wówczas procedura wyświetla komunikat że katalog usunięto => ioresult = 0.

Schody zaczynają się gdy próbujemy usunąć katalog z zawartością. Wówczas wyskakuje tylko 'Press Enter to continue', żadnego komunikatu o błędzie, a folder naturalnie nie jest usunięty:(

Jakieś pomysły dlaczego??

PS.

Istnieje jakaś procedura która umożliwia usunięcie katalogu z zawartoscią? (chodzi mi o gotową, a jak nie ma to ostatecznie sam napisze;)


([alex]) #2
  gotoxy(20,16);ioresult = 0 then

(Przemekbaranowski) #3

działa, dzięx;)


(Simplex111) #4

Gotowej procedury, która usuwałaby niepusty katalog, w Pascalu nie ma (zapewne ze względów bezpieczeństwa). Pascal to program DOSowy, a tam nie było czegoś takiego jak znane z Windows - przenoszenie plików i folderów do kosza. Po skasowaniu pliku odzyskanie go bez specjalnych narzędzi (programów) było trudne, a po pewnym czasie używania dysku wręcz niemożliwe.

Procedurę taką można oczywiście napisać, choć jest to trochę skomplikowane.

  1. Sprawdzamy, czy katalog zawiera jakieś pliki - procedura FindFirst

  2. Jeśli nie zawiera, kasujemy katalog i to koniec naszej procedury

  3. Jeśli zawiera, kasujemy plik zwrócony przez tę procedurę i szukamy w pętli następnych plików (procedura FindNext ), które również kasujemy.

Tu mała uwaga: trzeba sprawdzać atrybuty plików i ew. zmienić, bo nie można usunąć pliku tylko do odczytu (ReadOnly)

  1. Warunek zakończenia pętli sprawdzamy odczytując zmienną DosError i po skasowaniu wszystkich plików, kasujemy również katalog

Więcej na temat tych procedur znajdziesz w pomocy ekranowej Pascala.

Oczywiście na koniec trzeba dać jakieś ostrzeżenie, prośbę o potwierdzenie, żeby niechcący nie narobić sobie kłopotu wpisując np. MyRmDir('C:\Windows')


([alex]) #5

Przed punktem 1. trzeba sprawdzić czy katalog zawiera inne katalogi - tez FindFirst, katalogi można usuwać rekurencyjnie.


(Simplex111) #6

Oczywiście masz rację, zapomniałem o tym napisać.

Jednak konieczność sprawdzania, czy katalogi nie zawierają podkatalogów i zastosowanie rekurencji powoduje skomplikowanie kodu a tym samym zwiększa możliwość pomyłki. Postanowiłem więc pójść na skróty. Oto kod:

program KasujKatalog;

{$m 8192, 0, 0}

uses Dos;

begin

  SwapVectors;

  Exec('C:\WINDOWS\System32\cmd.exe', '/C RD /S/Q D:\KATALOG');

  SwapVectors;

  if DosError = 0 then Writeln('Katalog skasowany');

  Readln;

end.

Kasuje całe drzewo katalogów. Prosto, szybko i skutecznie, a wszystko zawarte w kilku linijkach kodu. Jest tylko jeden problem. który mnie nurtuje. Nie mogę zapisać procedury Exec w taki sposób, aby automatycznie znaleźć interpreter poleceń, gdy jest w nietypowym miejscu:

Exec(GetEnv('ComSpec'), '/C RD /S/Q D:\KATALOG');

Przy takim zapisie pojawia się błąd o nieprawidłowym przełączniku polecenia RD , tak jakby było to polecenie z jakiegoś starego DOSa, gdzie takie przełączniki jeszcze nie występowały. Postanowiłem to sprawdzić wykonując dwie instrukcje:

Exec('C:\WINDOWS\System32\cmd.exe', '/C VER');

Exec(GetEnv('ComSpec'), '/C VER');

Oto wyniki jakie otrzymałem kolejno:Microsoft Windows XP [Wersja 5.1.2600] - dla 'C:\WINDOWS\System32\cmd.exe' MS-DOS wersja 5.00.500 - dla GetEnv('ComSpec') Dodam, że zmienna środowiskowa ComSpec wskazuje właśnie na ten plik, czyli:

ComSpec=C:\WINDOWS\system32\cmd.exe

Ciekawe! Czyżby Windows XP zawierał w sobie starego DOSa z 1991r. :slight_smile:


([alex]) #7

Trochę to mija się z sensem, czy nie prościej odpalić SHFileOperation wrzucająć wspomniany folder do kosza, z możliwością ewentualnego odtwarzania?


(Simplex111) #8

Zdaję sobie sprawę, że ten mój program to trochę sztuka dla sztuki, ale ma swoje zalety: jest prosty, krótki i robi co potrzeba.

Spróbuj napisać krótszy kod kasujący całe drzewo katalogów używając do tego funkcji SHFileOperation (w dowolnym języku)