2010-08-01 13 views
5

Hey Leute, ich versuche, die ausgewählten Dateien eines Ordners, den der Benutzer verwendet, zu bekommen. Ich habe den folgenden Code, der bereits ausgeführt wird, aber nur auf Desktop-Dateien:Erhalte ausgewählte Ordner mit WinAPI

private string selectedFiles() 
{ 
    // get the handle of the desktop listview 
    IntPtr vHandle = WinApiWrapper.FindWindow("Progman", "Program Manager"); 
    vHandle = WinApiWrapper.FindWindowEx(vHandle, IntPtr.Zero, "SHELLDLL_DefView", null); 
    vHandle = WinApiWrapper.FindWindowEx(vHandle, IntPtr.Zero, "SysListView32", "FolderView"); 

    //IntPtr vHandle = WinApiWrapper.GetForegroundWindow(); 

    //Get total count of the icons on the desktop 
    int vItemCount = WinApiWrapper.SendMessage(vHandle, WinApiWrapper.LVM_GETITEMCOUNT, 0, 0); 
    //MessageBox.Show(vItemCount.ToString()); 
    uint vProcessId; 
    WinApiWrapper.GetWindowThreadProcessId(vHandle, out vProcessId); 
    IntPtr vProcess = WinApiWrapper.OpenProcess(WinApiWrapper.PROCESS_VM_OPERATION | WinApiWrapper.PROCESS_VM_READ | 
    WinApiWrapper.PROCESS_VM_WRITE, false, vProcessId); 
    IntPtr vPointer = WinApiWrapper.VirtualAllocEx(vProcess, IntPtr.Zero, 4096, 
    WinApiWrapper.MEM_RESERVE | WinApiWrapper.MEM_COMMIT, WinApiWrapper.PAGE_READWRITE); 
    try 
    { 
     for (int j = 0; j < vItemCount; j++) 
     { 
      byte[] vBuffer = new byte[256]; 
      WinApiWrapper.LVITEM[] vItem = new WinApiWrapper.LVITEM[1]; 
      vItem[0].mask = WinApiWrapper.LVIF_TEXT; 
      vItem[0].iItem = j; 
      vItem[0].iSubItem = 0; 
      vItem[0].cchTextMax = vBuffer.Length; 
      vItem[0].pszText = (IntPtr)((int)vPointer + Marshal.SizeOf(typeof(WinApiWrapper.LVITEM))); 
      uint vNumberOfBytesRead = 0; 
      WinApiWrapper.WriteProcessMemory(vProcess, vPointer, 
      Marshal.UnsafeAddrOfPinnedArrayElement(vItem, 0), 
      Marshal.SizeOf(typeof(WinApiWrapper.LVITEM)), ref vNumberOfBytesRead); 
      WinApiWrapper.SendMessage(vHandle, WinApiWrapper.LVM_GETITEMW, j, vPointer.ToInt32()); 
      WinApiWrapper.ReadProcessMemory(vProcess, 
      (IntPtr)((int)vPointer + Marshal.SizeOf(typeof(WinApiWrapper.LVITEM))), 
      Marshal.UnsafeAddrOfPinnedArrayElement(vBuffer, 0), 
      vBuffer.Length, ref vNumberOfBytesRead); 
      string vText = Encoding.Unicode.GetString(vBuffer, 0, 
      (int)vNumberOfBytesRead); 
      string IconName = vText; 

      //Check if item is selected 
      var result = WinApiWrapper.SendMessage(vHandle, WinApiWrapper.LVM_GETITEMSTATE, j, (int)WinApiWrapper.LVIS_SELECTED); 
      if (result == WinApiWrapper.LVIS_SELECTED) 
      { 
       return vText; 
      } 
     } 
    } 
    finally 
    { 
     WinApiWrapper.VirtualFreeEx(vProcess, vPointer, 0, WinApiWrapper.MEM_RELEASE); 
     WinApiWrapper.CloseHandle(vProcess); 
    } 
    return String.Empty; 
} 

Ich habe versucht, den Fenstergriff mit GetForegroundWindow() zu bekommen und dann ohne Erfolg die SHELLDLL_DefView nennen.

Also wie kann ich die ersten 3 Zeilen ändern, um mir das Handle des aktuellen Ordners in Gebrauch zu bekommen?

+0

Haben Sie eine Idee, warum vText immer leer ist? returns "\ 0 \ 0 \ 0 \ 0 \ 0" – Leila

+0

@abatishchev Wissen Sie, warum Dateinamen zurückgegeben werden \ 0 \ 0 \ 0 – Leila

Antwort

4

Das ist eine Menge zu hacken, etwas zu tun, das explizit von den verschiedenen Shell-Objekten und Schnittstellen unterstützt wird. Zugegeben, die Dokumentation macht es nicht leicht erkennbar, aber die Funktionalität ist da. Raymond Chen wrote a great article über die Verwendung dieser Schnittstellen. Es scheint keinen Weg zu geben, den "aktuellen" Ordner zu bekommen, obwohl ich denke, dass Sie die HWNDs bekommen und sehen können, ob irgendwas das Vordergrundfenster ist.

+0

Thx für den Link werde ich das überprüfen! – MUG4N

2

vielen Dank. Du hast mir die richtige Richtung gegeben. Es ist möglich, die ausgewählten Dateien eines Ordners zu erhalten:

/// <summary> 
/// Get the selected file of the active window 
/// </summary> 
/// <param name="handle">Handle of active window</param> 
/// <returns></returns> 
public String getSelectedFileOfActiveWindow(Int32 handle) 
{ 
    try 
    { 
     // Required ref: SHDocVw (Microsoft Internet Controls COM Object) 
     ShellWindows shellWindows = new SHDocVw.ShellWindows(); 

     foreach (InternetExplorer window in shellWindows) 
     { 
      if (window.HWND == handle) 
       return ((Shell32.IShellFolderViewDual2)window.Document).FocusedItem.Path; 
     }     
    } 
    catch (Exception) 
    { 
     return null; 
    } 
    return null; 
} 
+1

Sie müssen das COM-Objekt SHDocVw (Microsoft Internet Controls) als Referenz für Ihr Projekt hinzufügen. – boulaycote

+0

können Sie bitte den Code zeigen, um die Variable handle und sagen, wie die Funktion GetSelectedFileOfActiveWindow aufgerufen werden main() – akki

+0

@ MUG4N Ich habe tatsächlich Probleme bei der Erstellung einer Handle, vielleicht weil ich sehr neu in C# bin. Können Sie mir bitte in irgendeine Richtung zeigen? Jede Hilfe wird sehr geschätzt. Danke – akki