Announcement

Collapse
No announcement yet.

SHfileoperation

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • SHfileoperation

    mich interessiert brennend ob ich mit shfileoperation verzeichnisbäume
    löschen,kopieren oder verschieben kann!! da würde bei meinem dateimanager
    einiges an source-Code wegfallen!!!

    bitte um hilfe!!!

    mfg

    markus lemcke
    Herzliche Grüße

    Markus Lemcke
    barrierefreies Webdesign

  • #2
    Hallo Markus,

    mit der Win32-API-Funktion <b>SHFileOperation</b> können auch vollständige Verzeichnisbäume kopiert, verschoben und gelöscht werden. Allerdings gibt es bei den sogenannten <b>Special Folders</b> einige Ausnahmen - normale Verzeichnisse sind davon nicht betroffen. Dazu die gesuchten Beispiele:

    <b>1. Verzeichnisbaum kopieren</b>:
    <pre>
    uses ShellAPI;

    procedure TForm1.ButtonMoveDirClick(Sender: TObject);
    var
    aSHFOS : TSHFileOpStruct;
    szFrom : array[0..128] of Char;
    szTo : array[0..128] of Char;
    begin
    // Puffervariablen initialisieren (Doppel-Null!)
    FillChar(aSHFOS, Sizeof(aSHFOS), #0);
    FillChar(szFrom, Sizeof(szFrom), #0);
    FillChar(szTo, Sizeof(szTo), #0);
    // Ausgangs- und Zielverzeichnis festlegen
    StrPCopy(szFrom, 'C:\Temp\Out\*.*');
    StrPCopy(szTo, 'T:\Tmp');
    with aSHFOS do
    begin
    Wnd := Handle;
    wFunc := FO_COPY;
    pFrom := @szFrom;
    pTo :=@szTo;
    fFlags := FOF_NOCONFIRMATION or FOF_RENAMEONCOLLISION;
    fAnyOperationsAborted := False;
    hNameMappings := nil;
    lpszProgressTitle:= nil;
    end;
    ShFileOperation(aSHFOS);
    end;
    </pre>

    <b>2. Verzeichnisbaum löschen</b>:
    <pre>
    procedure TForm1.ButtonDeleteDirClick(Sender: TObject);
    var
    aSHFOS : TSHFileOpStruct;
    szFrom : array[0..128] of Char;
    begin
    // Puffervariablen initialisieren (Doppel-Null!)
    FillChar(aSHFOS, Sizeof(aSHFOS), #0);
    FillChar(szFrom, Sizeof(szFrom), #0);
    // Zu löschendes Verzeichnis definieren
    StrPCopy(szFrom, 'C:\Test\StdOut');
    with aSHFOS do
    begin
    Wnd := Handle;
    wFunc := FO_DELETE;
    pFrom := @szFrom;
    fFlags := FOF_NOCONFIRMATION or FOF_ALLOWUNDO;
    fAnyOperationsAborted := False;
    end;
    ShFileOperation(aSHFOS);
    end;
    </pre&gt

    Comment


    • #3
      Ich möchte hier nochmals das Thema "Löschen von Ordnern unter Windows NT 4" aufgreifen.<br>
      Zum Löschen verwende ich folgende Routine:<br>
      <br>
      function ShellDelete( Handle: THandle;<br>
      const Source: string;<br>
      Options: Byte): Boolean;<br>
      var<br>
      shellinfo: TSHFILEOPSTRUCT;<br>
      begin<br>
      with shellinfo do begin<br>
      wnd:= Handle;<br>
      wfunc:= FO_DELETE;<br>
      pFrom:= PChar(Source + #0);<br>
      pTo:= nil;<br>
      fFlags:= Options;<br>
      end;<br>
      result:= ((SHFileOperation(shellInfo) = 0) and not shellInfo.fAnyOperationsAborted);<br>
      end;<br>
      <br>
      procedure TForm1.Button2Click(Sender: TObject);<br>
      begin<br>
      ShellDelete(Handle, 'c:\Test1', FOF_ALLOWUNDO);<br>
      end;<br>
      <br>
      <br>
      Alternativ teste ich auch mitder von Herrn Kosch veröffentlichten procedure<br>
      <br>
      Die Struktur der Testordner ist die folgende:<br>
      C:\Test1\Test2<br>
      in Test1 und Test2 befinden sich Dateien.<br>
      Ziel ist es den Ordner Test1 komplett mit allen Dateien und Ordner in den Papierkorb zu verschieben.<br>
      Vor dem Ordner Test1 können sich auch noch weitere Ordner befinden.<br>
      <br>
      Die Testmaschine: NT-Server 4 mit Service Pack 5, Internet Explorer 4<br>
      Das Testprogramm wurde mit Delphi 4 SP 3 und alternativ mit Delphi 5 übersetzt.<br>
      <br>
      ------------<br>
      Erster Test:<br>
      Geht man in den Explorer und öffnet in Ordner Test1 eine Datei und löscht parallel dazu mit dem Testprogramm den Ordner Test1 passiert folgendes:<br>
      Nachdem die Dateien im Ordner Test2 und der Ordner Test2 unwiderruflich (nicht in den Papierkorb) gelöscht wurden wird folgende Meldung angezeigt:<br>
      "Der Ordner Test1 kann nicht entfernt werden: Eine Zugriffsverletzung ist aufgetreten.
      Die Quell- oder Zieldatei ist möglicherweise geöffnet."<br>
      Nach OK werden auch die restlichen Dateien unwiderruflich gelöscht. Der Ordner Test1 wird nicht entfernt.<br>
      ------------<br>
      Zweiter Test:<br>
      Geht man in den Explorer, öffnen Test2 und löscht parallel dazu mit dem Testprogramm den Ordner Test1 passiert folgendes: <br>
      Folgende Meldung wird angezeigt:<br>
      "Test1 kann nicht gelöscht werden: Zugriff wurde verweigert.
      Stellen Sie sicher, daß der Datenträger weder voll noch
      schreibgeschützt ist und die Datei gerade nicht
      verwendet wird."<br>
      Nach OK werden keine Dateien gelöscht.<br>
      ------------<br>
      Auffällig ist, daß auch andere Anwendungen Probleme mit dem Löschen von Ordnern haben.<br>
      Installiert man ein Programm mit Install Shield dann bleibt nach der Installation ein Ordner "_istmp0.dir" im Temp-Ordner zurück.<br>
      Das De-Installationsprogramm dagegen kann auch Ordner löschen, die durch den Explorer geöffnet sind.<br>
      ------------<br>
      <br>
      Die Frage ist nun: Beim wem liegt der Mega-Bug ? Bei mir ? Bei Delphi ? Bei NT ?<br>
      <br>
      mfg<br>
      Dietmar<br>
      <br>
      Hinweis: Windows 95 löscht immer alle Dateien, egal ob welche davon geöffnet sind

      Comment


      • #4
        Hallo,

        im Win32 SDK ist extra vermerkt, das man mit Windows 9x (im Gegensatz zu NT)auch Dateien mit offenen Kernel-Objekten löschen kann. Das Problem mit NT liegt also in den strengenen Schutzmechanismen. In einer Ausgabe der Zeitschrift <i>Microsoft System Journal</i> (Jahr 98 oder 99?) wurde ein C++-Programm im Sourcecode vorgestellt, mit dem man programmgesteuert alle Handles auf eine Datei ermitteln und "abräumen" kann (das Tool listet alle Prozesse auf, die auf diese Datei zugreifen). Das Abräumen passiert normalerweise beim Beenden des Prozesses, der die Datei einmal "angefasst" hat.

        Wenn das Verzeichnis im Explorer angezeigt wird, hat der Explorer alle Dateien in diesem Verzeichnis zumindestens einmal gelesen (Datum; Grösse etc.). Nicht ohne Grund fordern alle Setup-Programme auf, alle (!) anderen Windows-Anwendungen zu schliessen

        Comment


        • #5
          Hallo,<br>
          das ist ein Unding, ich sage NT: "Verschiebe den Ordner inkl. allem was darunter ist in den Papierkorb". NT bemerkt, daß ein Objekt, welche sich unten den zu löschenden Objekten befindet, geöffnet ist und löscht daraufhin alle Objekte unwiederruflich (nix Papierkorb, siehe Test1) !<br>
          mfg<br>
          Dietma

          Comment


          • #6
            Hallo,

            der Papierkorb ist primär als Rettungsinstrument für "oberflächliche" Anwender gedacht - aber nicht ein verlässlicher Ort für Sicherungskopien. Daher ist es auch nicht relevant, ob die vom Programm gelöschten Dateien im Papierkorb landen oder nicht. Wenn der Papierkorb nur eine kleine Grösse hat, und es werden sehr viele (grosse) Dateien gelöscht, entfernt Windows ganz "offiziell" alte Einträge, um Platz zu schaffen. Man darf also niemals davon ausgehen, eine gelöschte Datei in <b>jedem</b> Fall dort wiederzufinden. Diese Besonderheiten werden in der Hilfe zur API-Funktion dokumentiert

            Comment

            Working...
            X