Autor Beitrag
D. Annies
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: Do 20.01.11 20:10 
Hi, Delpher,

ich kopiere per Delphi-Programm viele Dateien z.B. von D nach H.
Uv's werden angelegt, alles läuft bestens.
Gegen Ende der umfangreichen Transaktion tritt der obige Fehler auf mit der Erläuterung:

Der aktuelle Prozess verwendet alle Handles der zulässigen Höchstanzahl für Windows Managerobjekte
Prozess wurde angehalten ...

Was ist denn da los?

Gruß, Detlef

_________________
ut vires desint, tamen est laudanda voluntas
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: Do 20.01.11 20:53 
Das bedeutet wohl, dass du die Dateihandles beim Kopieren nicht wieder freigibst. Und wenn alle verfügbaren Handles von dir in Beschlag genommen sind, ist Schluss.
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: Do 20.01.11 21:41 
Klingt sehr plausibel!
Woran erkenne ich ein Dateihandle? Wie vergebe / löse ich ein Dateihandle?
Gruß, Detlef

_________________
ut vires desint, tamen est laudanda voluntas
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: Do 20.01.11 21:44 
Das kommt ja drauf an wie du kopierst...

Nebenbei zeigen der Taskmanager bzw. der Process Explorer auch an wie viele Handles ein Programm gerade verwendet.
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: Do 20.01.11 21:56 
Ich kopiere folgendermaßen:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
if (fileexists(home_filename)) and (fileexists(work_filename)) then
          begin

            ///////////////////////////  ! Stunde So/Wi wegcodieren

            if (FileDateToDateTime(FileAge(work_filename)) <> FileDateToDateTime(FileAge(home_filename))) and
                            (fileage(work_filename) + 3600 <> FileAge(home_filename)) and
                            (fileage(work_filename)        <> FileAge(home_filename) + 3600then
            begin
              erg := xmessagedlg('ArchivBit wurde gesetzt' +#13 +
                       'Soll    ' + work_filename + ' '+#13+ datetimetostr(filedatetodatetime(FileAge(work_filename))) +#13+
                       'durch '   + home_filename + ' '+#13+ datetimetostr(filedatetodatetime(FileAge(home_filename))) +#13+
                       ' ersetzt werden?', mtConfirmation, [mbYes, mbno, mbcancel], ['ja''nein''Abbrechen'], self.font);
                                                             //  ???
              case erg of mryes    : CopyFile(PChar(home_filename), PChar(work_filename), FALSE);
                          mrcancel : raus := true;
              end;
            end
            // else showmessage(work_filename + ' ist von der Zeitumstellung betroffen');
          end             {CreateDir oder forcedirectories(label30.caption+uvname);}
          else
          if (fileexists(home_filename)) and (not fileexists(work_filename)) then
          begin               // Verzeichnisname + FindRec.Name
            erg := xmessagedlg('Soll '+ work_filename + #13' angelegt werden?', mtConfirmation,
                     [mbYes, mbNo, mbcancel], ['ja''nein''Abbrechen'], self.font);
            case erg of mryes    : begin                  //label30.caption+uvname
                                     if not directoryexists(ziel+uvname) then
                                       CreateDir(ziel+uvname);
                                     CopyFile(PChar(home_filename), PChar(work_filename), TRUE);
                                   end;
                        mrcancel : raus := true;
            end;
          end;

Das Handle ist wohl der PChar (??)
(Wie) Geht es anders / besser?
Gruß, Detlef

Moderiert von user profile iconNarses: Delphi-Tag repariert.

_________________
ut vires desint, tamen est laudanda voluntas
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: Do 20.01.11 22:02 
Da ist kein Handle, das du explizit benutzt. In den verwendeten Delphifunktionen wird das ziemlich sicher alles richtig freigegeben.

Ich habe aber einen Verdacht:
Ich rate einmal, dass du FindFirst usw. benutzt um nach den Dateien zu suchen. Kann es sein, dass du vergessen hast, diese Suchhandles mit FindClose auch wieder zu schließen? ;-)
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: Do 20.01.11 23:05 
Ich dachte erst: Volltreffer, aber ich glaube, nicht:
Die komplette Proc:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
Procedure TBuchMain.FindFiles (aPath, aFindMask: String; aWithSub: Boolean);
Var  FindRec                       : tSearchRec;
     home_filename, work_filename,
     Pfad, uvname, start, ziel     : string;
     n, erg                        : integer;
     raus                          : boolean;
Begin
  raus := false;
  If (aPath = ''or (aFindMask = ''then Exit;
  If aPath[Length(aPath)] <> '\' Then  aPath := aPath + '\';
  Pfad := aPath;
  If FindFirst (aPath + aFindMask, faAnyFile - faDirectory, FindRec) = 0 Then
  Repeat
    If (FindRec.Name <> '.'and (FindRec.Name <> '..'Then
    begin
      if aktuser <> 'an s' then                           // normaler User
      begin           // die benötigten Projektdateien
        if (pos('home.', FindRec.Name) > 0or
           (pos('.pas',  FindRec.Name) > 0or (pos('.dfm',  FindRec.Name) > 0or
           (pos('.res',  FindRec.Name) > 0or (pos('.exe',  FindRec.Name) > 0or
           (pos('.dpr',  FindRec.Name) > 0)
          OR          // die nicht benötigten Projektdateien
           (pos('.ddp',  FindRec.Name) > 0or (pos('.dof',  FindRec.Name) > 0or
           (pos('.dsk',  FindRec.Name) > 0or (pos('.dcu',  FindRec.Name) > 0or
           (pos('.cfg',  FindRec.Name) > 0then
        begin  end    // keine PrgDatei weitergeben
      end
      else                                                // SuperUser
      begin
        if (pos('.ddp',  FindRec.Name) > 0or  (pos('.dof',  FindRec.Name) > 0or
           (pos('.dsk',  FindRec.Name) > 0or  (pos('.dcu',  FindRec.Name) > 0or
           (pos('.cfg',  FindRec.Name) > 0then
        begin  end
        else
        if (FindRec.Name[1] = '_')             or (pos('.~', FindRec.Name) > 0)    or
           (pos('bestand_', FindRec.Name) > 0or (pos('temp_', FindRec.Name) > 0or
           (pos('Geburtstag_', FindRec.Name) > 0then
        begin
          showmessage(apath + findrec.name + ' wird gelöscht');
          DeleteFile(apath + FindRec.name)
        end
        else
        begin
          uvname := '';                            //aPath
          for n := pos('Buecherei\', Pfad)+10 to length(Pfad) do
            uvname := uvname + apath[n];
                                                                  // Stick nach Platte(oder 2.Stick)
          if aPath[1] = stdwert[1then  // START, von zB. C: nach zB. F: = ArbeitsVerz.
          begin
            start := stdwert; ziel := label30.Caption;
            home_filename := stdwert + uvname + FindRec.Name;
            work_filename := label30.caption + uvname + FindRec.name;
          end
          else //if aPath[1] = label30.Caption[1] then  // ENDE, von zB. F: nach zB. C: = Rücksicherung
          begin
            start := label30.Caption; ziel := stdwert;
            home_filename := label30.caption + uvname + FindRec.name;
            work_filename := stdwert + uvname + FindRec.name;
          end;
                                                  // getTimeZoneInformation, DateiAttribute
          if (fileexists(home_filename)) and (fileexists(work_filename)) then
          begin

            ///////////////////////////  ! Stunde So/Wi wegcodieren

            if (FileDateToDateTime(FileAge(work_filename)) <> FileDateToDateTime(FileAge(home_filename))) and
                            (fileage(work_filename) + 3600 <> FileAge(home_filename)) and
                            (fileage(work_filename)        <> FileAge(home_filename) + 3600then
            begin
              erg := xmessagedlg('ArchivBit wurde gesetzt' +#13 +
                       'Soll    ' + work_filename + ' '+#13+ datetimetostr(filedatetodatetime(FileAge(work_filename))) +#13+
                       'durch '   + home_filename + ' '+#13+ datetimetostr(filedatetodatetime(FileAge(home_filename))) +#13+
                       ' ersetzt werden?', mtConfirmation, [mbYes, mbno, mbcancel], ['ja''nein''Abbrechen'], self.font);
                                                             //  ???
              case erg of mryes    : CopyFile(PChar(home_filename), PChar(work_filename), FALSE);
                          mrcancel : raus := true;
              end;
            end
            // else showmessage(work_filename + ' ist von der Zeitumstellung betroffen');
          end             {CreateDir oder forcedirectories(label30.caption+uvname);}
          else
          if (fileexists(home_filename)) and (not fileexists(work_filename)) then
          begin               // Verzeichnisname + FindRec.Name
            erg := xmessagedlg('Soll '+ work_filename + #13' angelegt werden?', mtConfirmation,
                     [mbYes, mbNo, mbcancel], ['ja''nein''Abbrechen'], self.font);
            case erg of mryes    : begin                  //label30.caption+uvname
                                     if not directoryexists(ziel+uvname) then
                                       CreateDir(ziel+uvname);
                                     CopyFile(PChar(home_filename), PChar(work_filename), TRUE);
                                   end;
                        mrcancel : raus := true;
            end;
          end;
        end;
      end
    end;
  Until FindNext(FindRec) <> 0;
  FindClose(FindRec);

  If (Not aWithSub) or (raus) Then  Exit;    // keine UV's oder Abbruch dann raus
  If FindFirst (aPath + '*.*', faAnyFile, FindRec) = 0 Then
  Repeat     // In Unterverzeichnissen weiter suchen
    If (FindRec.Name <> '.'and (FindRec.Name <> '..'Then
      If Boolean (FindRec.Attr and faDirectory) Then  // wenn es sich um ein Verzeichnis handelt
        If ((FindRec.Attr and faDirectory) <> 0then
          FindFiles(aPath + FindRec.Name, aFindMask, aWithSub);  // Rekursion
  Until FindNext(FindRec) <> 0;
  FindClose(FindRec);
End;


Uff, Detlef

_________________
ut vires desint, tamen est laudanda voluntas
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: Do 20.01.11 23:38 
Dann bleibt nur im Taskmanager bzw. besser dem Process Explorer auf die Handles zu achten und zu schauen ob und wo deren Anzahl zunimmt.
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: Fr 21.01.11 07:42 
Ich habe keine Ahnung, wie ich dabei vorgehen könnte. :(((

(Nun, den Process Manager habe ich, aber damit umgehen kann ich nicht)

_________________
ut vires desint, tamen est laudanda voluntas
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: Fr 21.01.11 08:08 
Im Anhang einmal ein Screenshot. Das sind die Eigenschaften eines Prozesses. Und dort steht die Handleanzahl. Wenn du jetzt im Debugger schrittweise durchgehst, siehst du wo diese steigt oder sinkt.
Und wenn sie bei der selben Operation immer weiter steigt und nie wieder auf den alten Wert zurückgeht, stimmt etwas nicht.
Einloggen, um Attachments anzusehen!
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: Fr 21.01.11 10:54 
Es läuft doch darauf hinaus, dass ich da im Code einen Logikfehler eingebaut habe,
kann den jemand auch so erkennen? - Ich vermute ihn bei der Rekursion am Proc-Ende.
Ich krieg den Fehler nicht raus :( (trotz guter Hilfe bisher)
Detlef

_________________
ut vires desint, tamen est laudanda voluntas
zuma
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 660
Erhaltene Danke: 21

Win XP, Win7, Win 8
D7 Enterprise, Delphi XE, Interbase (5 - XE)
BeitragVerfasst: Fr 21.01.11 11:49 
Ich find merkwürdig, das du eine Methode 'FindFiles' hat, die sucht UND kopiert, beides in einem. Mein Lösungsansatz wäre gewesen, 2 Methoden zu haben:

Eine Methode, die die zu kopierenden Dateien ermittelt (und wirklich auch nur das macht) und z.b als Liste wieder gibt
und
eine Methode, die anhand einer übergebenen Liste Dateien kopiert (ala kopiere(xDateiliste, xZiel).

dein Findclose wird erst nach abarbeiten der repeatschleife aufgerufen, du kopierst aber innerhalb der schleife.

_________________
Ich habe nichts gegen Fremde. Aber diese Fremden sind nicht von hier! (Methusalix)
Warum sich Sorgen ums Leben machen? Keiner überlebts!
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: Fr 21.01.11 12:36 
Hi, zuma,
das ist richtig, aber wenn ich das Findclose in die Schleife setze, wird immer nur eine Datei
pro Verzeichnis kopiert.
Es sind zwar 1348 Dateien insgesamt, aber nicht > 1000 in einem UV!
Detlef

_________________
ut vires desint, tamen est laudanda voluntas
zuma
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 660
Erhaltene Danke: 21

Win XP, Win7, Win 8
D7 Enterprise, Delphi XE, Interbase (5 - XE)
BeitragVerfasst: Fr 21.01.11 14:38 
Hallo Detlef,
das ist richtig, aber mein Lösungsvorschlag war ja auch nicht, das FindClose in die Schleife zu verlagern, sondern deine Schleife in 2 aufzuteilen. In der jetzigen Variante wirste das Kopieren raus und merkst dir dort stattdessen die Dateie, die du kopieren möchtest (z.B. in einer Stringlist). Das Ergebnis (also die gefüllte Stringlist) übergibst du dann an die 2te, neu zu erstellende Methode, die dann das eigentliche Copy macht.

_________________
Ich habe nichts gegen Fremde. Aber diese Fremden sind nicht von hier! (Methusalix)
Warum sich Sorgen ums Leben machen? Keiner überlebts!
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: Fr 21.01.11 19:45 
hab jetzt eine Menge versucht, noch ohne Erfolg: Ich scheitere an der Erstellung der Proc,
die dann für das Kopieren en bloc zuständig sein soll. Wobei ja kopiert oder ersetzt werden soll!
Wie könnte die aussehen, sprich welcher Befehl gilt da? CopyFile(), CopyFileEx() oder was?

_________________
ut vires desint, tamen est laudanda voluntas
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: Fr 21.01.11 20:04 
An SHFileOperation könntest du auch gleich mehrere Dateien auf einmal übergeben.

Welchen Befehl du da nutzt, ist im Grunde nicht so wichtig. Wobei ich vermute, dass SHFileOperation mit jeweils mehreren Dateien einen Geschwindigkeitsvorteil bringen könnte.
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Fr 21.01.11 20:32 
user profile iconjaenicke hat folgendes geschrieben Zum zitierten Posting springen:
An SHFileOperation könntest du auch gleich mehrere Dateien auf einmal übergeben.

Welchen Befehl du da nutzt, ist im Grunde nicht so wichtig. Wobei ich vermute, dass SHFileOperation mit jeweils mehreren Dateien einen Geschwindigkeitsvorteil bringen könnte.

Ist in der Regel 5%, teilweise bis zu 15% langsamer als die Dateien selbst mit geeigneter Puffergröße zu kopieren. Hatte da mal selber mir ein Tool geschrieben, was immer Meilenweit vor dem Explorer fertig war.

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: Fr 21.01.11 20:40 
Aber leider nicht mit D6Enter. :(

_________________
ut vires desint, tamen est laudanda voluntas
D. Annies Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 1843

windows 7
D6 Enterprise, D7 Pers und TD 2006
BeitragVerfasst: Sa 22.01.11 08:17 
So, ich hab's gelöst:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
if (fileexists(home_filename)) and (not fileexists(work_filename)) then
          begin               // Verzeichnisname + FindRec.Name
            erg := xmessagedlg('Soll '+ work_filename + #13' angelegt werden?', mtConfirmation,
                     [mbYes, mbNo, mbcancel], ['ja''nein''Abbrechen'], self.font);
            case erg of mryes    : begin                  //label30.caption+uvname
         
                                     if not directoryexists(ziel+uvname) then
                                       CreateDir(ziel+uvname);
                                     CopyFile(PChar(home_filename), PChar(work_filename), TRUE);

                                   end;
                        mrcancel : raus := true;
            end;
          end;


Ich lasse die xmessagedld-Abfrage weg, nur die drei Zeilen "in der Mitte" lasse ich stehen, damit auf jeden Fall
(ohne Nachfrage) kopiert wird!
Yes! Uff!
Gruß, Detlef
P.S. Weiß jemand, warum das die Handles "spart"?

_________________
ut vires desint, tamen est laudanda voluntas
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: Sa 22.01.11 09:10 
user profile iconD. Annies hat folgendes geschrieben Zum zitierten Posting springen:
P.S. Weiß jemand, warum das die Handles "spart"?
Naja, ich weiß ja nicht was xmessagedlg für eine Funktion ist, aber ich könnte wetten, dass da etwas nicht freigegeben wird...
Vielleicht der angezeigte Dialog selbst? Der beinhaltet natürlich gleich mehrere Handles und Objekte.

Mit FastMM kannst du solche nicht freigegebenen Sachen aber auch finden.