AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Problem mit CopyFile

Ein Thema von Berni68 · begonnen am 4. Sep 2016 · letzter Beitrag vom 6. Sep 2016
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    
Berni68

Registriert seit: 9. Jan 2006
Ort: Villingen
162 Beiträge
 
Delphi XE5 Professional
 
#1

Problem mit CopyFile

  Alt 4. Sep 2016, 10:53
Hallo zusammen,

ein Programm, das nunmehr ca. 3 Jahre einwandfrei funktioniert hat, stürzt jetzt reproduzierbar ab.
In einer Prozedur werden lokale Dateien auf den Server kopiert und lokal gelöscht.
Ziel sieht so aus:
\\Server\pfad\unterverzeichnis\datei_i.pdf

Delphi-Quellcode:
procedure TJobServerForm.VerschiebePdf;
var
  files: TStrings;
  i:integer;
  ziel, zielpfad: string;
  ok: boolean;
begin
  files:= TStringList.Create;
  GetFilesMatchInPath(LokalPdfDir, '*.pdf', files, false);
  try
    for i:=0 to files.Count-1 do begin
      try
        memo.Lines.Add(IntToStr(i+1) + '/' + IntToStr(files.Count)+ ' ' + files[i]);
        zielpfad:= WithBackSlash(PdfDir) + ExportSubDirFromFileName(files[i]);
        if not DirectoryExists(zielpfad) then ForceDirectories(zielpfad);
        ziel:= zielpfad + ExtractFileName(files[i]);
ShowMessage('#');
        ok:= CopyFile(PChar(files[i]), PChar(ziel), false);
        if ok then DeleteFile(files[i]);
      except
        RaiseLastOSError;
      end;
    end;
  finally
    files.Free;
  end;
end;
Die Schleife wird das erste mal korrekt durchlaufen (Datei wird korrekt kopiert und lokal gelöscht), beim zweiten mal immer Absturz,
und zwar genau bei der Anweisung nach ShowMessage('#');
except wird nicht durchlaufen.
Es sieht so aus als ob das nur bei .pdf-Dateien passiert, da an anderer Stelle mit ähnichem Code nicht pdf dateien problemlos verarbeitet werden.
Da sich an dem Gesamtsystem nichts verändert hat ausser Betriebssystem und Virenscanner Updates sollte es wohl daran liegen.
Der Virenscanner ist TrendMicro
Angenommen es liegt am Virenscanner (meine Vermutung, die aber erst morgen durch Abschalten überprüft werden kann) nun die Frage:
Was kann man tun, ausser den Virenscanner für .pdf zu deaktivieren?
(CopyFile durch TMemoryStream Load / Save zu ersetzten, hab ich probiert: bringt nichts, identisches Ergebnis)
(Ich gehe davon aus, dass man den Virenscanner nicht dauerhaft deaktivieren wird)
Bernhard
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#2

AW: Problem mit CopyFile

  Alt 4. Sep 2016, 11:06
Wie heißt denn die Fehlermeldung?
Delphi-Quellcode:
except
  on e : Exception do begin
    ShowMessage(e.Message);
    // Aus der Doku: Raises an exception for the last occurring OS
    // or system library error.
    RaiseLastOsError; // Ist denn überhaupt so ein Fehler aufgetreten?
  end;
end;
Wird Except definitiv nicht durchlaufen?
Per Debugger und Breakpoint überprüft?
  Mit Zitat antworten Zitat
Berni68

Registriert seit: 9. Jan 2006
Ort: Villingen
162 Beiträge
 
Delphi XE5 Professional
 
#3

AW: Problem mit CopyFile

  Alt 4. Sep 2016, 11:25
Per Debugger und Breakpoint nicht überprüft, da das Programm bei einer Firma läuft in der ich nicht mehr arbeite.
D.h. Ich programmiere zuhause, übermittle die exe und lasse mir die Ergebnisse berichten.
Ich habe aber auch schon
ShowMessage('Exception');
direkt nach except eingefügt.
Die Meldung wird nie angezeigt, Programm ist abgestürzt.
In meiner Umgebung zuhause läuft alles problemlos. Habe allerdings auch keinen TrendMicro.
Bernhard
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#4

AW: Problem mit CopyFile

  Alt 4. Sep 2016, 12:14
Definiere bitte kurz: "Programm ist abgestürzt"

Das Programm ist "einfach" weg?
Keine Meldung bezüglich Zugriffsverletzungen ...

Einfach so aus Taskleiste, Liste der laufenden Programm ... verschwunden?

Habe vor Jahren auch mal auf Systemen mit TrendMicro gearbeitet, weiß aber nicht mehr, ob und wie da protokolliert wird.

Gibt es da irgendwelche Logfiles ... in denen zum Zeitpunkt des Programmabsturzes irgendwas protokolliert wird?

Insgesammt Deine Routine "aussagefreudiger" machen:
(ungetestet hingeschrieben - als Idee)
Delphi-Quellcode:
procedure TJobServerForm.VerschiebePdf;
var
  files: TStrings;
  i:integer;
  ziel, zielpfad: string;
  ok: boolean;
  LogFile : String;
begin
  LogFile := Format('c:\TJobServerForm.VerschiebePdf.%s.log',[AnsiReplaceText(DateTimeToStr(Now),':','.')]);
  memo.Lines.Add(Format('Starte Routine: TJobServerForm.VerschiebePdf - %s',[DateTimeToStr(Now)]));
  memo.Lines.SaveToFile(LogFile);
  files := TStringList.Create;
  memo.Lines.Add(Format('vor GetFilesMatchInPath(%s, %s, files, false)',[LokalPdfDir,'*.pdf']));
  memo.Lines.SaveToFile(LogFile);
  GetFilesMatchInPath(LokalPdfDir, '*.pdf', files, false);
  memo.Lines.Add('gefundenen Dateien:');
  memo.Lines.Add(files.Text);
  memo.Lines.Add(Format('hinter GetFilesMatchInPath(%s, %s, files, false)',[LokalPdfDir,'*.pdf']));
  memo.Lines.SaveToFile(LogFile);
  try
    for i := 0 to files.Count - 1 do begin
      try
        memo.Lines.Add(Format('%d/%d %s',[i+1,files.Count,files[i]]));
        zielpfad := WithBackSlash(PdfDir) + ExportSubDirFromFileName(files[i]);
        memo.Lines.Add(Format('Zielpfad: %s',[ZielPfad]));
        if not DirectoryExists(zielpfad) then begin
          memo.Lines.Add(Format('ForceDirectories: %s',[ZielPfad]));
          ForceDirectories(zielpfad);
        end;
        ziel := zielpfad + ExtractFileName(files[i]);
        memo.Lines.Add(Format('Ziel: %s',[Ziel]));
        memo.Lines.Add(Format('vor CopyFile(%s,%s, false)',[files[i],ziel]));
        memo.Lines.SaveToFile(LogFile);
// ShowMessage('#'); // ist zwar schön
// ShowMessage(Files[i]); // dürfte aber aussagefähiger sein ;-)
        ok := CopyFile(PChar(files[i]), PChar(ziel), false);
        memo.Lines.Add(Format('hinter CopyFile(%s,%s, false)',[files[i],ziel]));
        memo.Lines.SaveToFile(LogFile);
        if ok then begin
          memo.Lines.Add(Format('vor DeleteFile: %s',[files[i]]));
          memo.Lines.SaveToFile(LogFile);
          if DeleteFile(files[i]) then begin
            memo.Lines.Add(Format('erfolgreich: DeleteFile: %s',[files[i]]));
          end else begin
            memo.Lines.Add(Format('nicht erfolgreich: DeleteFile: %s',[files[i]]));
          end;
          memo.Lines.Add(Format('hinter DeleteFile: %s',[files[i]]));
          memo.Lines.SaveToFile(LogFile);
        end;
      except
        on e : Exception do begin
          memo.Lines.Add(Format('Exception bei Datei: %s',[files[i]]));
          memo.Lines.Add(Format('Fehlermeldung: %s',[e.Message]));
          memo.Lines.SaveToFile(LogFile);
          RaiseLastOSError;
        end;
      end;
    end;
  finally
    files.Free;
  end;
  memo.Lines.Add(Format('Beende Routine: TJobServerForm.VerschiebePdf - %s',[DateTimeToStr(Now)]));
  memo.Lines.SaveToFile(LogFile);
end;
Lassen sich anhand der so erstellten Logfiles irgendwelche Systematiken erkennen?

Programmabsturz beim zweiten Aufruf immer bei der
  • ersten Datei?
  • gleichen Datei?
  • einem bestimmten Pfad?
Das memo.Lines.SaveToFile(LogFile); alle Nas' lang aufzurufen, ist sicherlich nicht performant, aber man hat so die Chance bei beliebigen Zwischenschritten die Meldungen auf die Platte zu bekommen, da bei 'nem Absturz beim folgenden Befehl, die Infos aus dem Memo schon weggeschrieben sind.

Alternative 'ne Loggingfunktion nehmen, die die Ausgabedatei vor jedem Schreibvorgang öffnet und nach jedem Schreibvorgang schließt.
  Mit Zitat antworten Zitat
Berni68

Registriert seit: 9. Jan 2006
Ort: Villingen
162 Beiträge
 
Delphi XE5 Professional
 
#5

AW: Problem mit CopyFile

  Alt 4. Sep 2016, 12:35
Hallo nahpets,

abgestürzt heisst: "Programm ist einfach weg!"
Keine Meldungen.
Meine Routinen waren/sind schon aussagefreudiger.
Ich habe hier nur das ganze 'etwas' komprimiert und auf das wesentliche reduziert.

Ich kann, nach etlichen Tests, sicher sagen, dass der Absturz in der Zeile
CopyFile(PChar(files[i]), PChar(ziel), false);
passiert, mit oder ohne Zuweisung des Ergebnisses an die Boolsche Variable 'ok'
Ich kann sicher sagen, dass die übergebenen Dateinamen korrekt sind.
Es ist fast immer die 2. pdf bei der das Programm abschmiert. Einmal von vielen Tests war es erst die 3. pdf
Wenn das Programm dann neu gestartet wird, wird die Datei, bei der es zuvor abgestürzt ist (identische Pfad- und Dateinaman wie zuvor)
korrekt kopiert und gelöscht, und stürzt dann wiederum bei der nächsten pdf ab.
D.h. Wenn z.B. 13 pdf-Dateien im Verzeichnis sind, kann man durch 13 maliges Starten des Programmes die Aufgabe korrekt erledigen.
Ich habe auch schon mit Verzögerungen a la
sleep(2000);
oder langen Wartezeiten bei
ShowMessage('#');
rumprobiert, um Timingprobleme zu umgehen,
hat aber den Absturz (praktisch immer bei der 2. pdf) nicht verhindert.
Bernhard

Geändert von Berni68 ( 4. Sep 2016 um 13:11 Uhr)
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#6

AW: Problem mit CopyFile

  Alt 4. Sep 2016, 13:02
Befremdlich das Ganze.

Es gibt auch noch function MoveFile(lpExistingFileName, lpNewFileName: PChar): BOOL; Wäre das mal eine Testalternative?

Dadurch könnte die Kombination von CopyFile und DeleteFile (eventuell) entfallen.

Wo hast Du ShowMessage bzw. Sleep(2000) hingemacht?

Zwischen CopyFile und DeleteFile?

Weiß nicht, wie CopyFile arbeitet. Läuft das Kopieren im Hintergrund oder wartet das Programm, bis CopyFile fertig ist und löscht erst dann mit DeleteFile?

Eventuell trennst Du mal CopyFile und DeleteFile.

Aus der momentanen Routine DeleteFile rausnehmen und erst am Ende in 'ner eigenen Schleife aufrufen?
Delphi-Quellcode:
procedure TJobServerForm.VerschiebePdf;
var
  files: TStrings;
  i:integer;
  ziel, zielpfad: string;
  ok: boolean;
begin
  files := TStringList.Create;
  GetFilesMatchInPath(LokalPdfDir, '*.pdf', files, false);
  try
    for i := files.Count - 1 DownTo 0 do begin
      try
        memo.Lines.Add(IntToStr(i+1) + '/' + IntToStr(files.Count)+ ' ' + files[i]);
        zielpfad: = WithBackSlash(PdfDir) + ExportSubDirFromFileName(files[i]);
        if not DirectoryExists(zielpfad) then ForceDirectories(zielpfad);
        ziel := zielpfad + ExtractFileName(files[i]);
        ok := CopyFile(PChar(files[i]), PChar(ziel), false);
      except
        RaiseLastOSError;
      end;
    end;
    for i := files.Count - 1 DownTo 0 do begin
      try
        zielpfad := WithBackSlash(PdfDir) + ExportSubDirFromFileName(files[i]);
        ziel := zielpfad + ExtractFileName(files[i]);
        if FileExists(Ziel) then files.Delete(i);
      except
        RaiseLastOSError;
      end;
    end;
    If files.Count > 0 then begin
      ShowMessage('Es konnten nicht alle Dateien kopiert und gelöscht werden!' + #13#13 + Files.Text);
    end;
  finally
    files.Free;
  end;
end;
  Mit Zitat antworten Zitat
Berni68

Registriert seit: 9. Jan 2006
Ort: Villingen
162 Beiträge
 
Delphi XE5 Professional
 
#7

AW: Problem mit CopyFile

  Alt 4. Sep 2016, 13:12
Hallo nahpets,

ich habe testweise bereits das DeleteFile schon ganz weggelassen.
Ohne Erfolg.
CopyFile, wie oben erwähnt, durch einen TMemoryStream mit LOKAL lesen und ENTFERNT schreiben ersetzt.
Immer das gleiche, bei der 2. pdf ist das Programm weg.

Auch noch interessant:
Wenn ich das kopieren auf einen anderen PC umleite funktioniert alles problemlos.
Es muss also was mit dem Zielrechner zu tun haben.
Morgen werde ich veranlassen daß der Virenscanner temporär abgestellt wird (zumindest für pdf's) (hab dazu leider nicht das erforderliche Passwort, macht eine Fremdfirma...)
Gleichzeitig lagere ich das kopieren mal aus und erstelle hierzu lediglich eine Batch-Datei (XCOPY ....), die dann von Hand angestossen werden soll/muss.
Bin gespannt was dann passiert.

Allerdings kann ich mir nicht erklären wie ein entfernter Rechner das lokale programm abschiessen kann.
Ich hätte eigentlich erwartet, daß das Kopieren lediglich fehlschlägt, was dann aber mit dem Rückgabewert False entsprechend behandelt werden kann
Bernhard
  Mit Zitat antworten Zitat
nahpets
(Gast)

n/a Beiträge
 
#8

AW: Problem mit CopyFile

  Alt 4. Sep 2016, 13:36
Allerdings kann ich mir nicht erklären wie ein entfernter Rechner das lokale programm abschiessen kann.
Beim Kopieren scheint etwas zu passieren, mit dem die API-Funktion CopyFile von Windows nicht zurecht kommt und sich da "final" verabschiedet, so dass das ganze Programm "weg" ist. "Schuld" ist da schon der Rechner, auf dem die Kopierakton läuft, da er mit einem "unbekannten Verhalten der Gegenseite" nicht zurecht kommt.

Die Idee mit der Batch-Datei und XCopy ist ok.
Wenn das "händisch" funktioniert, könntest Du die Batchdatei ja auch erstellen und dann aus Deinem Programm per ShellExecute aufrufen, dann muss der Anwender nix "zu Fuß" machen und kann dann auch nichts vergessen.
Oder die XCopys direkt aus dem Programm per ShellExecute aufrufen.

Statt XCopy wäre es dann aber auch eine Überlegung wert "Move" zu verwenden, dann musst Du dich nicht um das Löschen der Quelldatei kümmern.
Und es kann keine Probleme bei der Synchronisation zwischen dem Kopieren und dem Löschen geben.
Desweiteren: Bei Dateien, die nach dem Aufruf von Move noch "übrig" sind, weiß man, dass da was schief ging und man löscht nicht versehentlich Dateien, bei denen der Kopiervorgang (warum auch immer) gescheitert ist.

Schöner wär's ja schon, wenn's denn 'ne vernünftige Begründung für dieses "seltsame" Verhalten gäbe.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.052 Beiträge
 
Delphi 12 Athens
 
#9

AW: Problem mit CopyFile

  Alt 4. Sep 2016, 13:39
das nunmehr ca. 3 Jahre einwandfrei funktioniert hat,
Delphi-Quellcode:
procedure TJobServerForm.VerschiebePdf;
        ok:= CopyFile(PChar(files[i]), PChar(ziel), false);
        if ok then DeleteFile(files[i]);
      except
        RaiseLastOSError;
      end;
Im Fehlerfall hat das noch niemals einwandfrei funktioniert, da diese APIs praktisch niemals eine Exception werfen, sondern nur einen Fehlercode liefern (Result=False + GetLastError).

Warum eigentlich nicht Bei Google suchenMoveFile?

Delphi-Quellcode:
if not EineWinAPI(...) then
  RaiseLastError;

Also ja, es kann sein, dass der VirenScanner eine neue Datei noch geöffnet hat, wenn du zugreifen willst.
Genauso kann z.B. auch ein Explorer-Plugin der Grund sein.
Im Explorer werden doch Dateiinformationen angezeigt ... dafür öffnet das Plugin die Dateien, um das auszulesen. (da macht Adobe gern mal Problemchen)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.

Geändert von himitsu ( 4. Sep 2016 um 13:43 Uhr)
  Mit Zitat antworten Zitat
Berni68

Registriert seit: 9. Jan 2006
Ort: Villingen
162 Beiträge
 
Delphi XE5 Professional
 
#10

AW: Problem mit CopyFile

  Alt 4. Sep 2016, 14:08
Hallo himitsu,

da hast du recht.
Tatsächlich ist die ursprüngliche Variante auch:

if CopyFile(PChar(files[i]), PChar(ziel), false) then DeleteFile(files[i]);

Wenn es dann schief ging, warum auch immer, z.B. die Zieldatei ist geöffnet, wird die Datei nicht gelöscht.
Beim nächsten Durchlauf des Programmes ca. 5min später wird es dann wieder probiert usw.
Hat soweit eingentlich funktioniert.

Ich werde es auf jeden Fall auch mit MoveFile probieren.

Allerdings funktionierte auch der Versuch in der ich NUR kopiert habe NICHT.
Also ausschließich:

CopyFile(PChar(files[i]), PChar(ziel), false);

Ohne Delete.
Auch hier immer Absturz bei der 2. pdf
Da greife ich doch auf die neue Datei garnicht zu? Oder?
Bernhard
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 4  1 23     Letzte »    

 

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 15:53 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz