2010-08-01 70 views
5

嘿傢伙我試圖獲取用戶正在使用的文件夾的選定文件。我有以下的代碼已經被,但只能在電腦上的文件運行:使用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; 
} 

我就先用GetForegroundWindow()的窗口句柄,然後調用SHELLDLL_DefView沒有成功。

那麼,如何更改前3行來獲取當前正在使用的文件夾的句柄?

+0

你知道爲什麼vText總是空的嗎?返回「\ 0 \ 0 \ 0 \ 0 \ 0」 – Leila 2018-01-25 00:00:14

+0

@abatishchev你知道爲什麼文件名返回爲\ 0 \ 0 \ 0 – Leila 2018-01-25 00:17:40

回答

4

這是很多黑客做一些明確受各種shell對象和接口支持的東西。授予文檔並不容易發現,但功能在那裏。 Raymond Chen wrote a great article關於使用這些接口。似乎沒有辦法獲得「當前」文件夾,但我想你可以得到HWND並查看是否有前景窗口。

+0

Thx的鏈接我會檢查出來! – MUG4N 2010-08-03 06:39:54

2

非常感謝。你給了我正確的方向。有可能獲得文件夾的選定文件:

/// <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

您將不得不添加SHDocVw(Microsoft Internet控件)COM對象作爲您項目的參考。 – boulaycote 2012-12-07 14:49:15

+0

你可以請顯示代碼來獲取變量句柄,並告訴如何調用函數getSelectedFileOfActiveWindow在main() – akki 2014-01-26 18:44:12

+0

@ MUG4N我實際上有創建句柄的問題,也許是因爲我對c#很新。你能不能指出我的方向?任何幫助都會大大降低。謝謝 – akki 2014-01-27 22:35:27