Autor Beitrag
Karl_F
Hält's aus hier
Beiträge: 8



BeitragVerfasst: 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: Mo 18.04.11 05:46 
Hallo und :welcome:

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:
ausblenden 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



BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: 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:

ausblenden 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:

ausblenden 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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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



BeitragVerfasst: Mo 18.04.11 10:28 
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mo 18.04.11 10:33 
user profile iconLuckie hat folgendes geschrieben Zum zitierten Posting springen:
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 :oops:

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
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 1654
Erhaltene Danke: 244

WIN10,PuppyLinux
FreePascal,Lazarus
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mo 18.04.11 10:39 
user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:
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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mo 18.04.11 10:42 
user profile iconHorst_H hat folgendes geschrieben Zum zitierten Posting springen:
Hallo,

Zitat:
die Umbenennung soll in einer rekursiven Dateisuche erfolgen.

Du beginnst dabei auch sicher in der utersten Ebene?

Gruß Horst


Ich denke :oops: 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: 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! :D

War das das ganze Problem?
jaenicke
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 19312
Erhaltene Danke: 1747

W11 x64 (Chrome, Edge)
Delphi 11 Pro, Oxygene, C# (VS 2022), JS/HTML, Java (NB), PHP, Lazarus
BeitragVerfasst: 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: Mo 18.04.11 11:04 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
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 :oops: 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 Threadstarter
Hält's aus hier
Beiträge: 8



BeitragVerfasst: 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