Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi SHBrowseForFolder öffnet Dateien? (https://www.delphipraxis.net/81627-shbrowseforfolder-oeffnet-dateien.html)

himitsu 30. Nov 2006 14:03


SHBrowseForFolder öffnet Dateien?
 
Moin ihr,

ich hab da ein kleines Problem mit SHBrowseForFolder (wer hätt's gedacht -.-'').


Und zwar scheint dieses Dateien/Verzeichnisse zu öffnen (per CreateFile, oder so) und nicht wieder zu schließen. :shock:



Anfangs dachte ich schon der Fehler liegt in meinem Programm und hab mich halt totgesucht. :cry:

Die Auswirkung ist, daß die Dateien/Verzeichnisse z.B. nicht mehr gelöscht werden können.



Dat is sozusagen mein Code:
Delphi-Quellcode:
Type TFolderRec = Record
    PreSelectedFolder, Title: PWideChar;
  End;
  PFolderRec = ^TFolderRec;

Function FolderCallback(Dlg: HWND; Msg: LongWord; LParam: Pointer; Data: PFolderRec): LongWord; StdCall;
  Var Temp: TFileNameW;

  Begin
    Case Msg of
      BFFM_INITIALIZED: Begin
        SendMessage(Dlg, WM_SETTEXT, 0, Integer(PChar(ProgName)));
        If Data^.PreSelectedFolder <> nil Then
          SendMessageW(Dlg, BFFM_SETSELECTIONW, LongInt(True), Integer(Data^.PreSelectedFolder));
      End;
      BFFM_VALIDATEFAILED: Begin
        Result := 1;
        Exit;
      End;
    End;
    Result := 0;
  End;

Function BrowseForFolder(Wnd: HWND; Const Caption, PreSelectedFolder: WideString; Var SelectedDir: WideString): Boolean;
  Var BI: TBrowseInfoW;
    FolderRec: TFolderRec;
    pidlResult: PItemIDList;
    Temp: TFileNameW;
    Malloc: iMalloc;

  Begin
    Result := False;
    ZeroMemory(@BI, SizeOf(BrowseInfoW));
    BI.hwndOwner := Wnd;
    BI.lpszTitle := PWideChar(Caption);
    BI.ulFlags  := BIF_NEWDIALOGSTYLE or BIF_SHAREABLE;
    BI.lpfn     := @FolderCallBack;
    BI.lParam   := Integer(@FolderRec);
    FolderRec.Title            := PWideChar(Integer(Caption));
    FolderRec.PreSelectedFolder := PWideChar(Integer(PreSelectedFolder));
    pidlResult                 := SHBrowseForFolderW(BI);
    If pidlResult = nil Then Exit;
    If SHGetPathFromIdListW(pidlResult, @Temp[0]) Then Begin
      Result     := True;
      SelectedDir := Temp;
    End;
    If SHGetMalloc(Malloc) = S_OK Then
      Try
        Malloc.Free(pidlResult);
      Finally
        Malloc := nil;
      End;
  End;
Und in der angehängten EXE werden zum Test die offenen FileHandles gezählt.
Die aktuelle Anzahl steht im Hauptfenster, unterm "Source"-Label.

Mein BrowseForFolder ist im Anhang auf'm [Start]-Dialog (der Pfeil-Button neben den Edits) erreichbar ... sobald er erscheint tauchen plötzlich 3-4 FileHandles auf und die verschwinden erst wieder, wenn das Programm beendet wird. :wall:



Die Handles entstehen auch direkt in SHBrowseForFolder. (davor 0 und danach meist 3)
An der FolderCallback kann es auch nicht liegen, denn wenn diese fehlt, das selbe Ergebnis.


Am BIF_SHAREABLE liegt es auch nicht. (der Zugriffstest lag ja nahe)


Ach ja, rein theoretisch könnte ich die offenen FileHandles auslesen, SHBrowseForFolder aufrufen und dann alle zusätzlichen FileHandles schließen,
aber ich denk dieses wäre nicht ganz optimal, vorallem da nicht klar ist was dann passieren könnte.
Hab die FileHandle zwar schon einige male über'n Process Explorer abgeschossen ... ohne Probleme, allerdings würde ich sowas derzeit nich auf fremden Rechnern versuchen wollen. :engel:


System: WinXP SP2

shmia 1. Dez 2006 17:57

Re: SHBrowseForFolder öffnet Dateien?
 
Hast du vielleicht einen schlauen Virenscanner am Laufen, der am liebsten im aktuellen Verzeichnis scannt?

mirage228 1. Dez 2006 18:03

Re: SHBrowseForFolder öffnet Dateien?
 
Hi,

Hab' ne Vermutung:
Vielleicht ist es einfach der Explorer, welcher dieses Verzeichnis als "CurrentDir" festlegt und dann eine Art lock darauf hält. Welcher Prozess das genau ist, kannst Du evtl. mit WhoLockMe herausfinden.

mfG
mirage228

ste_ett 1. Dez 2006 18:37

Re: SHBrowseForFolder öffnet Dateien?
 
Den Rückgabewert der Funktion musst du wieder freigeben. :)

Zitat:

It is the responsibility of the calling application to free the returned IDList by using CoTaskMemFree.

himitsu 1. Dez 2006 18:52

Re: SHBrowseForFolder öffnet Dateien?
 
Was ist ein VirenScanner?

Nee, ma im Ernst.
Derzeit hab ich doch eh kein INet am "heimischen" PC und da gibt es dort aktuell keinen Virenscanner und eine FireWall ist ja eh nutzlos :roll:


Der Explorer ist es nicht, ich sagte ja, die zusätzlichen Handles liegen nachweislich im "eigenem" Prozess.

Und sie tauchen ganz genau beim ersten Öffnen/Anzeigen (wärend der Laufzeit des Programmes) dieses Dialogs auf.

In dem Label werden ja auch nur die FileHandles dieses Prozesses gezählt.
Es ist auch kein Hook auf FileCreate ... es werden einfach alle 100ms die FileHandles (also Handles auf Verzeichnisse, oder Dateien, ausgenommen Pipes) aufgelistet und mitgezählt.

@ste_ett:
das mache ich doch, oder seh ich das falsch, selbst wenn ich das Result vergessen würde, dann sollte das doch nur ein Handle sein (ein Result = ein Verzeichnis = ein Handle ???)
Delphi-Quellcode:
Malloc.Free(pidlResult);
Werde aber dennoch mal mit CoTaskMemFree rumspielen.

himitsu 4. Dez 2006 16:55

Re: SHBrowseForFolder öffnet Dateien?
 
Zitat:

Zitat von himitsu
Werde aber dennoch mal mit CoTaskMemFree rumspielen.

Keine Verbesserung.

Hab es jetzt erstmal so gelößt (auch wenn es mir nicht so richtig gefällt), daß alle Handles nach Aufruf dieser Box geschlossen werden.


Aber is dat auch bei anderen so?
Falls ma wer prüfen möchte ... hSync.exe > [Start] > [<] (Verzeichnisbrowser) ... wärend der offen ist, sollten keine File-Handles vorhanden sein, also eine 0 in der ersten Spalte der TreeView (Dateiliste) ... hab die Zahl mal an 'ne andere Stelle verschoben ^^


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:01 Uhr.

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