Delphi-PRAXiS
Seite 9 von 11   « Erste     789 1011      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Software-Projekte der Mitglieder (https://www.delphipraxis.net/26-software-projekte-der-mitglieder/)
-   -   Pegasus: Luckies persönliches Synchronisationstool (https://www.delphipraxis.net/41226-pegasus-luckies-persoenliches-synchronisationstool.html)

CG2003 7. Aug 2006 12:06

Re: Pegasus: Luckies persönliches Synchronisationstool
 
Hallo Luckie,

ich habe mal die MD5-Unit von Assarbad gegen die von Matthias Fichtner (www.fichtner.net) ausgetauscht, und entsprechende leichte Änderungen an Deinem Programm vorgenommen.

Aber auch mit dieser Unit bleibt dein Programm "hängen". Bei mir besonders bei Word-Dokumenten (*.doc).

Also denke ich, hat es mit der Erstellung der MD5-Hashes anscheinend nichts zu tun, das Dein Programm "stehen bleibt".

himitsu 7. Aug 2006 12:26

Re: Pegasus: Luckies persönliches Synchronisationstool
 
Duhu Luckie,

hab mir och ma deinen Pegasus angeguckt und irgendwie läuft da was nich so, wie soll bestimmt soll. :shock:

Isch kann of die Verzeichnisbuttons rumklicken wie isch will, aber nüschts passiert. :cry:


Nagut, also hab'sch ma selber kompiliert, nachgeguckt und siehe da ... CoInitialize(nil) liefet S_FALSE und wenn es dat macht, machst du überhauptnüschts ... nichma 'ne Fehlermeldung hast'e für mich. *eingeschnapptsei*


So läuft es ^^
Delphi-Quellcode:
var
  CoInit: Boolean;
begin
  Result := false;

  CoInit := CoInitialize(nil) = S_OK;
  try
    ...
  finally
    if CoInit then CoUninitialize;
  end;

Hier ma ä leicht verständliches Beispiel:
Delphi-Quellcode:
program Project1;

uses Windows, SysUtils, ActiveX;

var CoInit1, CoInit2: Boolean;

begin
  CoInit1 := CoInitialize(nil) = S_OK;
  try

    CoInit2 := CoInitialize(nil) = S_OK;
    try
      MessageBox(0, PChar('CoInit1=' + BoolToStr(CoInit1, True)
        + ', CoInit2=' + BoolToStr(CoInit2, True)), '', 0);
    finally
      if CoInit2 then CoUninitialize;
    end;

  finally
    if CoInit1 then CoUninitialize;
  end;
end.
Man kann nur einmal initialisieren (jedenfalls bei mir > D7 + WinXP SP2).

Und da es über TApplication.Initialize schonmal aufgerufen wurde ...

Delphi-Quellcode:
procedure TApplication.Initialize;
begin
  if InitProc <> nil then TProcedure(InitProc);
end;
InitProc zeigt auf InitComObj, wo entweder CoInitializeEx oder CoInitialize ofjerufen wird.

Mann ohh mann, da such man sich dumm und dusslig und dann isses da, wo man hätte als erstes nachsehen können/sollen. :wall:
Code:
//ComObj.pas ... die von D7
initialization
  ...
  if not IsLibrary then
  begin
    SaveInitProc := InitProc;
    [color=clRed]InitProc := @InitComObj;[/color]
  end;

Und dat hier...
Zitat:

---------------------------
Pegasus.exe - Fehler in Anwendung
---------------------------
Die Ausnahme "Unbekannter Softwarefehler" (0x0eedfade) ist in der Anwendung an der Stelle 0x7c81eb33 aufgetreten.


---------------------------
OK Abbrechen
---------------------------
es macht sich besonders gut, wenn sich (noch) nichts in der ListView1 befindet :zwinker:
Delphi-Quellcode:
procedure TForm1.ListView1DblClick(Sender: TObject);
var
  s: String;
begin
  s := ListView1.Items[Listview1.ItemIndex].Caption;
  ShellExecute(Handle, 'open', PChar(s), nil, nil, SW_SHOWNORMAL);
end;

Luckie 7. Aug 2006 12:37

Re: Pegasus: Luckies persönliches Synchronisationstool
 
Werde ich mal einpflegen in meiner Version. Danke für deine Mühe.

himitsu 7. Aug 2006 12:59

Re: Pegasus: Luckies persönliches Synchronisationstool
 
Ach ja, hätt ich beinah vergessen ...

du löschst doch alle leeren Ordner?


Na ja, es is zwar nich so schlimm, aber manchma lege ich 'nen Ordner schon an, bevor ich diesen (Tage/Wochen später) mal nutze (befülle).

Tja, diese Ordner würden dann ja von dir gelöscht.
OK, ich könnte den/die dann zwar irgendwann mal wieder neu anlegen (z.B. erst wenn er wirklich benötigt wird).

Eventuell wäre da ein Test ob ein Ordner im Quellverzeichnis vorhanden ist besser, als "nur" nachzusehn ob was in dem Ordner drin ist.

himitsu 19. Aug 2006 00:16

Re: Pegasus: Luckies persönliches Synchronisationstool
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

So, hab hier mal ein winziges "Linux und Windows, wir mögen uns nicht"-Problem:
(hatte unter Linux 'ne Datei [FAT32] gespeichert und in Windows war die dann ärgerlicher Weise nicht auffindbar ... von der Größe her könnte sie nun wieder aufgetaucht sein, nur daß man sie halt nich lesen kann und sie och noch so'nen netten Datumsfehler enthält, abgesehn von dem komischen Dateinamen)
Zitat:

---------------------------
Pegasus.exe - Fehler in Anwendung
---------------------------
Die Ausnahme "Unbekannter Softwarefehler" (0x0eedfade) ist in der Anwendung an der Stelle 0x7c81eb33 aufgetreten.


---------------------------
OK Abbrechen
---------------------------



---------------------------
Anwendungsfehler
---------------------------
Exception EConvertError in Modul Pegasus.exe bei 00007F8E.

Ungültiges Argument zum Codieren des Datums.


---------------------------
OK
---------------------------



---------------------------
Pegasus.exe - Fehler in Anwendung
---------------------------
Die Ausnahme "Unbekannter Softwarefehler" (0x0eedfade) ist in der Anwendung an der Stelle 0x7c81eb33 aufgetreten.


---------------------------
OK Abbrechen
---------------------------



---------------------------
Anwendungsfehler
---------------------------
Exception EOSError in Modul Pegasus.exe bei 0000D576.

Systemfehler. Code: 5.

Zugriff verweigert.


---------------------------
OK
---------------------------



---------------------------
Pegasus.exe - Fehler in Anwendung
---------------------------
Die Ausnahme "Unbekannter Softwarefehler" (0x0eedfade) ist in der Anwendung an der Stelle 0x7c81eb33 aufgetreten.


---------------------------
OK Abbrechen
---------------------------



---------------------------
Error
---------------------------
Runtime error 217 at 0040D576
---------------------------
OK
---------------------------
Grund siehe Bild.

FileAge lieferte -1 als Ergebnis.

Meine Lösung:
Delphi-Quellcode:
// fill Listview
with Form1 do
begin
  Listview1.Items.BeginUpdate;
  for i := 0 to slNewFiles.Count - 1 do
  begin
    ...
    ListItem.SubItems.Add(Format('%f KB', [GetFileSize(PChar(slNewFiles.Strings[i])) / 1024]));
    try
      Listitem.SubItems.Add(DateTimeToStr(FileDateToDateTime(FileAge(slNewFiles.Strings[i]))));
    except
      Listitem.SubItems.Add('[ERROR]');
    end;
    Listitem.ImageIndex := 1;
  end;
dat dann natrülich och nochma bei den anderen beiden FileAge's in Unit1 ^^

Und dann bricht SHFileOperation die Operation ab, sobald ein Fehler auftritt, also alle nachfolgenden Dateien werden nich kopiert/gelöscht, aber dennoch erfolgreich aus der Liste ausgetragen.
Ich hatte das mal so gelöst, das bei 'nem Fehler dann nochmal die Dateien einzeln verarbeitet wurden, vorallem weil ich keine andere Möglichkeit sah Programmtechnich rauszufinden bei welcher Datei(en) der Fehler auftrat.

z.B.:
Delphi-Quellcode:
Function DeleteToRecycler(Const FileNames: TDynWideStringArray): Boolean;
  Var P: PWideChar;
    i, i2: Integer;
    ShellInfo: TSHFileOpStructW;

  Begin
    Result := False;
    P := nil;
    Try
      i := 0;
      For i2 := High(FileNames) downto 0 do If FileNames[i2] <> '' Then Inc(i, Length(FileNames[i2]) + 1);
      If i = 0 Then Exit;
      P := GetMemE(i * 2 + 4);
      ZeroMem(P, i * 2 + 4);
      For i2 := High(FileNames) downto 0 do If FileNames[i2] <> '' Then Begin
        Dec(i, Length(FileNames[i2]) + 1);
        CopyMem(Pointer(FileNames[i2]), P + i, Length(FileNames[i2]) * 2);
      End;
      ZeroMem(@ShellInfo, SizeOf(TSHFileOpStructA));
      ShellInfo.Func  := FO_DELETE;
      ShellInfo.opFrom := P;
      ShellInfo.Flags := FOF_NOCONFIRMATION or FOF_ALLOWUNDO or FOF_NOERRORUI;
      Result := SHFileOperationW(ShellInfo) = S_OK;
    Finally
      FreeMem(Pointer(P));
    End;
    If not Result Then Begin
      Result := True;
      For i := High(FileNames) downto 0 do
        If FileExists(FileNames[i]) Then Begin
          ZeroMem(@ShellInfo, SizeOf(TSHFileOpStructA));
          ShellInfo.Func  := FO_DELETE;
          ShellInfo.opFrom := Pointer(FileNames[i]);
          ShellInfo.Flags := FOF_NOCONFIRMATION or FOF_ALLOWUNDO or FOF_NOERRORUI;
          If SHFileOperationW(ShellInfo) <> S_OK Then Result := False;
        End;
    End;
  End;
bei If SHFileOperationW(ShellInfo) <> S_OK Then könnte man sich jetzt noch reinhängen und die Datei(en) ermitteln/speichern...


zum Thema "// create not existing folders":
Zitat:

Zitat von PSDK > SHFILEOPSTRUCT Structure
Copy and Move operations can specify destination directories that do not exist and the system will attempt to create them. The system normally displays a dialog box to ask the user if they want to create the new directory. To suppress this dialog box and have the directories created silently, set the FOF_NOCONFIRMMKDIR flag in fFlags.

(wäre vorallem unpraktisch, wenn man keine Dateien kopieren ließe, aber die "nötogen" Vereichnisse dennoch erstellt würden)

PS: die Häckchen, welche man vor die Dateinamen (da unten in der Liste) machen kann werden auch irgendwann mal ausgewertet?
(kann die beiden Dateien nicht vom Stick löschen ... Dateisystemfehler ... und auslassen kann ich sie ja auch nicht -.-'' )


Ach ja, weil ich's grad mal versucht hatte ... wie wäre es, wenn man da unten die Dateiliste sortieren könnte, indem man auf die süßen Spltenüberschriften klickt? *hundeblickaufsetz*
so, dat hatte ich vor ein paar Tagen verfaßt, inzwischen weiß ich auch noch, daß ein "ähnlicher" Fehler auftritt, wenn man z.B. eine Datei löscht, nachdem Pegasus die Datei eingelesen hatte, und sie nach dem Löschen anzeigen wollte (weil sie als neu/verändert erkannte ... vor dem Löschen) ... Datei existiert nicht mehr, daher Datumsfehler (-1)

Luckie 19. Aug 2006 02:04

Re: Pegasus: Luckies persönliches Synchronisationstool
 
Zu meiner Schand emuss ich gestehen, dass ich noch nicht dazu gekommen bin etwas an dem Programm zu machen. :oops:

himitsu 19. Aug 2006 10:02

Re: Pegasus: Luckies persönliches Synchronisationstool
 
och, hat ja Zeit ... hab für mich ja auch erstmal nur'n paar Workarounds eingebaut, dammit es ohne Abzustürzen läuft :)

ich war ja mehr üb das VCL von dir überrascht ;)

himitsu 29. Aug 2006 11:49

Re: Pegasus: Luckies persönliches Synchronisationstool
 
Moin Luckie ^^


erstmal hab ich ein Problem festgestellt, kann aber einfach nicht sagen woher es kommt o.O

und zwar, wenn ich meinen USB-Sick mit einem Verzeichnis auf der Platte synchronisiere, dann läuft erstmal das Erstellen der Dateilist normal ab, auch das Syncronisieren läuft ohne (scheinbar) Probleme durch,
nur wenn dich danach nochmal eine Dateiliste erstelle werden plötzlich wieder Unterschiede gefunden, obwohl doch nach dem Syncronisieren keine mehr vorhanden sein sollten. :gruebel:

Es gab auch keine Fehlermeldung, daß bestimmte Dateien nicht kopiert werden konnten, oder dergleichen.

Auch weiß ich nicht, oder die Dateien beim ersten Durchgang schon in der Dateiliste enthalten waren, oder ob sie schon dort übersehen wurden.


Ist bisher auch nur 2-mal aufgefallen und beim ersten Mal war's erst nach dem 3. Durchlauf alles synchron.
Beim 2. Mal hatte ich wenigstens mit 'nem eigenem (alten) Programm nochmal verglichen und die Unterschiede waren (nach dem 1. Durchlauf) wirklich noch da.

Konnte dieses aber im Debugger bisher noch nicht reproduzieren -.-''

Ach ja:
1 GB USB-Stick
im Durchschnit 500-900 MB mit 17.000-18.000 Dateien



Dann reagiert dein Programm manchmal nicht mehr ... vorwiegend, wenn man auf Abbrechen geklickt hatte und dann eine Weile was anderes machte (also der Pegasus im Hintergrund lag),
danach war dann die ganze Form komplett Weiß und er konnte nur noch über den taskmanager beendet werden.
(wobei dieses auch an meinem Windows liegen könnte ... ist ja etwas lediert, wie man an meinem Problemchen mit EM_SETCUEBANNER sieht -.-'' )




Nun noch ein kleiner Tipp bezüglich der Windows-Cache:
Du ließt die Dateien ja rückwärts ein, demnach würde ich FILE_FLAG_RANDOM_ACCESS bei CreateFile empfehlen.



Und ich weiß ja nicht wieviel du am Pegasus noch ändern willst, aber bei meiner Dateianzahl rechnet der schon echt lange beim Filtern/Anzeigen der Dateiliste (nach dem Suchen/Hashen der Dateien), vorallem wenn sich mal viel verändert hatte.
Ich denk mal ein Großteil dieser Zeit (anzeigen / ListBox füllen) könnte man verhindern, indem die Dateiinfos nich noch ein zweites Mal ausgelesen werden würden. (eventuell gleich bei der Dateisuche mit speichern? ... [size=2]GetFileSize und FileAge ruft ja für jede Datei einzeln nochmals FindFirstFile auf ... GetFileSize ruft FileExists, welches nochmals FileAge aufruft, womit dann pro Datei 3-mal FindFirstFile + die paar mal bei der Dateisuche aufgerufen wird ... dauert halt etwas, wenn die WindowsCache sich dann jedesmal nochmals auf dem langsamen USB-Stick vergewissert, daß sie noch aktuell ist[/size])
Zumindest ein FileExists/FileAge/FindFirstFile kann man leicht einsparren :mrgreen;
Code:
////////////////////////////////////////////////////////////////////////////////
// Procedure : GetFileSize
// Comment  : Returns the filesize

function GetFileSize(szFile: PChar): Int64;
var
  fFile                 : THandle;
  wfd                   : TWIN32FINDDATA;
begin
  result := 0;
  [color=darkred][s]if not FileExists(szFile) then exit;[/s][/color]
  fFile := FindFirstfile(pchar(szFile), wfd);
  if fFile = INVALID_HANDLE_VALUE then exit;
  [color=red]if wfd.dwFileAttributes and FILE_ATTRIBUTE_DIRECTORY = 0 then[/color]
    result := ([color=blue]Int64(wfd.nFileSizeHigh) shl 32[/color]) or wfd.nFileSizeLow;
  windows.FindClose(fFile);
end;

XeRo 29. Aug 2006 13:29

Re: Pegasus: Luckies persönliches Synchronisationstool
 
sieht super aus dein programm.
ist es auch netzwerktauglich?

himitsu 29. Aug 2006 15:18

Re: Pegasus: Luckies persönliches Synchronisationstool
 
theoretisch ja. (und praktisch vermutlich auch)

Du mußt nur die Ordner so angeben, wenn du es im Explorer machen würdest.
Nur in wieweit es bei geschützten Verzeichnissen geht müßte man testen.

Es geht halt nahezu alles was MSDN-Library durchsuchenFindFirstFile auch kann.

[add2]
MSDN-Library durchsuchenSHFileOperation sollte och mit beachtet werden, aber wenn das die selben Namenskonventionen hat, wie FindFirstFile, dann sollte sogar FTP kein Problem sein ^^


[add]
PS: der Fehler von nkaaa in #44 is och noch drin ... liegt wohl an der fehlenden Synchronisierung :angel2:


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:58 Uhr.
Seite 9 von 11   « Erste     789 1011      

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz