Autor |
Beitrag |
Karl_F
Hält's aus hier
Beiträge: 8
|
Verfasst: Mo 18.04.11 01:44
Hallo Forum,
ich bin neu hier und meine Delphi-Kenntnisse sind etwas eingerostet, aber folgendes Problem macht mich noch wahnsinnig... dabei sollte es eigentlich so einfach sein:
Problem in Kurzform: RenameFile funktioniert nicht in rekursiven Aufrufen
Es geht darum, mehrere Verzeichnisse umzubenennen. Ich verwende Delphi 7 und Windows XP. Folgender Code funktioniert:
procedure TForm1.Button1Click(Sender: TObject);
var src, dst: string;
begin
src:= 'E:\delphi\testordner';
dst:= 'E:\delphi\testordner_2';
renamefile(src, dst);
end;
Wenn ich nun aber mehrere Verzeichnisse rekursiv durchlaufe, anhand der darin enthaltenen Dateinamen dynamisch einen Verzeichnisnamen erstelle, mir diesen auch ausgeben lasse (z.B. alter Name: 'E:\texte', darin enthaltene Datei: 'meine_datei.txt', neuer Name: 'E:\meine_texte'), und dann innerhalb der rekursiv aufgerufenen Prozedur sage RenameFile(alterName, neuerName), dann passiert gar nichts!
Selbst wenn ich etwas weiter verschachtelt den hardcodierten Code von oben ausführe, passiert nichts!
Mit anderen Worten, RenameFile direkt bei einer ButtonClick-Prozedur funktioniert, weiter verschachtelt im Code funktioniert es nicht.
Ich muss aber über 1000 Verzeichnisse anhand der darin enthaltenen Dateinamen unbenennen und komme um einen verschachtelten Aufruf nicht umhin.
Bin allerdings mit meinem Delphi-Latein am Ende. Weiß jemand Rat?
Grüße, Karl
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 18.04.11 05:46
Hallo und
Nimm SHFileOperation und FO_MOVE als Funktion. Damit funktioniert das problemlos. Das ist die Funktion, die auch der Windows Explorer intern verwendet.
So ca. meine ich: Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13:
| var ShellOp: TSHFileOpStruct; src, dst: string; begin src:= 'E:\delphi\testordner'; dst:= 'E:\delphi\testordner_2'; ShellOp.Wnd := Handle; ShellOp.wFunc := FO_MOVE; ShellOp.pFrom := PChar(src + #0); ShellOp.pTo := PChar(dst + #0); ShellOp.fFlags := FOF_NOCONFIRMATION or FOF_SILENT; ShellOp.lpszProgressTitle := 'Verschiebe...'; SHFileOperation(ShellOp); |
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 18.04.11 09:01
RenameFile hat auch einen Rückgabewert und was sagt die Auswertung von GetLastError? So können wir auch nur raten. Ist die Umbenennung in einer rekursiven Dateisuche enthalten?
|
|
Karl_F 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mo 18.04.11 10:22
Hallo Sebastian,
ich hab es so gemacht (auch wenn ich nicht genau verstehe, was da passiert), es funktioniert aber nicht:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| procedure TForm1.RenDir(Src, Dst: string); var ShellOp: TSHFileOpStruct; begin ShellOp.Wnd := Handle; ShellOp.wFunc := FO_MOVE; ShellOp.pFrom := PChar(Src + #0); ShellOp.pTo := PChar(Dst + #0); ShellOp.fFlags := FOF_NOCONFIRMATION or FOF_SILENT; ShellOp.lpszProgressTitle := 'Verschiebe...'; SHFileOperation(ShellOp); end; |
Die Prozedur bekommt genau das übergeben, was sie braucht, habe es mit Einzelschritten getestet, es wird ein Verzeichnis angelegt mit dem neuen Namen, die Dateien hineingeschoben und dann versucht, das alte Verzeichnis zu löschen. Und hier bekomm ich den Fehler, dass das Verzeichnis nicht gelöscht werden kann, da andere Programme darauf zugreifen! Klar: mein eigenes hat ja noch in SR.name (vonTSearchRec) Zugriff darauf, oder?
Dieses hier www.swissdelphicente...showcode.php?id=1024
hatte ich schon gefunden gehabt, da passiert GAR NICHTS:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15:
| procedure TForm1.RenameDir(DirFrom, DirTo: string); var shellinfo: TSHFileOpStruct; begin with shellinfo do begin Wnd := 0; wFunc := FO_RENAME; pFrom := PChar(DirFrom); pTo := PChar(DirTo); fFlags := FOF_FILESONLY or FOF_ALLOWUNDO or FOF_SILENT or FOF_NOCONFIRMATION; end; SHFileOperation(shellinfo); end; |
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Mo 18.04.11 10:27
Hallo,
wird bei Änderung des Verzeichnisnamens überhaupt irgendetwas verschoben ????
Die Einträge auf die Dateien bleiben doch davon völlig unberührt.
Gruß Horst
|
|
Luckie
Ehemaliges Mitglied
Erhaltene Danke: 1
|
Verfasst: Mo 18.04.11 10:28
Luckie hat folgendes geschrieben : | RenameFile hat auch einen Rückgabewert und was sagt die Auswertung von GetLastError? So können wir auch nur raten. Ist die Umbenennung in einer rekursiven Dateisuche enthalten? |
Ich muss mich mal selber zitieren, weil es ja offenbar nicht angekommen ist. Baue da endlich mal eine gescheite Fehlerbehandlung ein, dann weißt du auch, warum der Aufruf fehlschlägt. Oder sollen wir hier ewig weiter raten bis es zufällig funktioniert?
|
|
Karl_F 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mo 18.04.11 10:33
Luckie hat folgendes geschrieben : | RenameFile hat auch einen Rückgabewert und was sagt die Auswertung von GetLastError? So können wir auch nur raten. Ist die Umbenennung in einer rekursiven Dateisuche enthalten? |
Hallo Luckie,
nicht so schnell, bin ja schon dabei
GetLastError sagt 32. Ja, die Umbenennung soll in einer rekursiven Dateisuche erfolgen.
The process cannot access the file because it is being used by another process.
Das passt ja zu den Erkenntnissen von oben.
Hmm... und nun?
Grüße, Karl
|
|
Horst_H
      
Beiträge: 1654
Erhaltene Danke: 244
WIN10,PuppyLinux
FreePascal,Lazarus
|
Verfasst: Mo 18.04.11 10:35
Hallo,
Zitat: | die Umbenennung soll in einer rekursiven Dateisuche erfolgen. |
Du beginnst dabei auch sicher in der utersten Ebene?
Gruß Horst
|
|
Karl_F 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mo 18.04.11 10:39
Horst_H hat folgendes geschrieben : | Hallo,
wird bei Änderung des Verzeichnisnamens überhaupt irgendetwas verschoben ????
Die Einträge auf die Dateien bleiben doch davon völlig unberührt.
Gruß Horst |
Dass offenbar ein Verzeichnis angelegt wird und die Dateien dort hinein verschoben werden, erscheint mir zwar sonderbar, aber wenn ich wie oben mit SHFileOperation arbeite, wird ein neues Verzeichnis angelegt, welches dann die Dateien enthält, und danach sollte dann das alte Verzeichnis gelöscht werden.
So hab ich das jedenfalls verstanden.
Grüße, Karl
|
|
Karl_F 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mo 18.04.11 10:42
Horst_H hat folgendes geschrieben : | Hallo,
Zitat: | die Umbenennung soll in einer rekursiven Dateisuche erfolgen. |
Du beginnst dabei auch sicher in der utersten Ebene?
Gruß Horst |
Ich denke  Es wird zunächst nach Verzeichnissen gesucht und dann, wenn eines gefunden wurde, die Suche rekursiv aufgerufen.
Soll ich die rekursive Suche posten? Hat ewig gedauert, bis ich die fertig hatte. Gibt es da echt nichts vorgefertigtes? Braucht man doch öfter...
So der Profi bin ich nicht, hab alles autodidakt gelernt.
|
|
Karl_F 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mo 18.04.11 10:51
Habe jetzt mal vor dem umbenennen FindClose(SR) gesagt. Dann sagt mir showmessage(SysErrorMessage(GetLastError)) zwar "Zugriff verweigert", aber es passiert genau das, was soll: Die Verzeichnisse werden umbenannt!
War das das ganze Problem?
|
|
jaenicke
      
Beiträge: 19312
Erhaltene Danke: 1747
W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
|
Verfasst: Mo 18.04.11 10:55
Klar, wenn du noch ein Handle auf das Verzeichnis offen hast, kann es nicht gehen. Eigentlich logisch, oder?
Und was heißt rekursiv? Das oberste Verzeichnis umbenennen reicht bei SHFileOperation...
|
|
Karl_F 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mo 18.04.11 11:04
jaenicke hat folgendes geschrieben : | Klar, wenn du noch ein Handle auf das Verzeichnis offen hast, kann es nicht gehen. Eigentlich logisch, oder?
Und was heißt rekursiv? Das oberste Verzeichnis umbenennen reicht bei SHFileOperation... |
Ja, eigentlich logisch, man muss nur drauf kommen  Ich habe jetzt allerdings einfach mit RenameFile gearbeitet.
Rekursiv ist die Suche, weil der Code ursprünglich zur rekursiven Suche mehrerer verschachtelter Verzeichnisse diente. Und ich muss ja jetzt auch in der obersten Ebene die Verzeichnisse finden, und dann gucken, wie die Dateien darin heißen (bzw. die erste Datei, die Namen folgen dem gleichen Schema). Die Verzeichnisse sollen ja anhand der Dateinamen bezeichnet werden.
Muss ich (bei RenameFile) den jetzigen Fehler 5 (Zugriff verweigert) so interpretieren, dass es keinen Fehler gab?
|
|
Karl_F 
Hält's aus hier
Beiträge: 8
|
Verfasst: Mi 20.04.11 11:39
Hallo,
das beste an Foren sind ja die Denkanstöße. In diesem Fall GetLastError. Ich habe es jetzt hinbekommen, vielen Dank nochmal.
Grüße, Karl_F
|
|