【问题标题】:Get list of selected files from Windows Desktop从 Windows 桌面获取选定文件的列表
【发布时间】:2013-09-30 13:13:18
【问题描述】:

我正在尝试从 Windows 桌面和资源管理器 Windows 中获取选定文件的列表。 要求是我应该能够从活动的资源管理器窗口或桌面检索当前选择。

在浏览了在线资源后,我设法将以下代码放在一起,但它没有提供桌面中选定项目的列表。

ArrayList selected = new ArrayList();
var shell = new Shell32.Shell();
IntPtr handle = IntPtr.Zero;
handle = GetForegroundWindow();
int intHandle = handle.ToInt32();

//For each explorer
foreach (InternetExplorer window in new ShellWindowsClass())
{

    if (window.HWND == (int)handle)
    {
        Shell32.FolderItems items = ((Shell32.IShellFolderViewDual2)window.Document).SelectedItems();
        foreach (Shell32.FolderItem item in items)
        {
            selected.Add(item.Path);
        }
    }
}

除此之外,我尝试了以下方法,但它只是给出了所有打开的资源管理器窗口中所有选定元素的列表,而忽略了桌面。

string filename; = Path.GetFileNameWithoutExtension(window.FullName).ToLower();
if (filename.ToLowerInvariant() == "explorer")
{
    Shell32.FolderItems items = ((Shell32.IShellFolderViewDual2)window.Document).SelectedItems();
    foreach (Shell32.FolderItem item in items)
    {
        //MessageBox.Show(item.Path.ToString());
        selected.Add(item.Path);
    }
}

所以我总是从资源管理器窗口中得到一个列表,即使没有打开资源管理器窗口也没有得到任何结果。当前的技术似乎完全忽略了桌面。

如果有人能帮助我从当前活动的窗口/桌面获取选定文件的列表,我将不胜感激。

谢谢。

【问题讨论】:

  • 您可以在桌面上获取选定的文件吗?如果是的话,你能告诉我该怎么做吗?请!

标签: c# windows visual-c++ windows-shell shell32


【解决方案1】:

桌面很容易,因为它仍然是列表视图,只需找到正确的句柄即可。列表视图是桌面句柄的子视图。

Desktop
+- Progman (for backward compatibility)
   +- Shell Def View
      +- SysListView32 (even under 64 bit)

那么你就可以对列表视图进行所有的列表视图操作了。但其他资源管理器窗口不包含列表视图。相反,他们使用带有DirectUIHWND 类的窗口,这对许多人来说是个谜。我刚刚找到一篇文章,描述了解开这个谜团的方法。

http://smartbear.com/forums?forumid=81&threadid=68427#68428

希望对你有帮助。

【讨论】:

    【解决方案2】:

    我认为您应该在进程之间进行通信。 以下主题会有所帮助。

    这是从桌面检索图标的示例。获取桌面项目列表及其当前位置。 http://social.msdn.microsoft.com/Forums/windows/en-US/d7df8a4d-fc0f-4b62-80c9-7768756456e6/how-can-i-get-desktops-icons-information-?forum=winforms

    这里的参数 LVM_GETITEMSTATE 可以在上面链接的示例代码中使用。 http://msdn.microsoft.com/en-us/library/windows/desktop/bb761053(v=vs.85).aspx

    祝你好运..

    【讨论】:

      【解决方案3】:
          using System.Runtime.InteropServices;
      
          public class ShellItems
          {
              [StructLayoutAttribute(LayoutKind.Sequential)]
              private struct LVITEM
              {
                  public uint mask;
                  public int iItem;
                  public int iSubItem;
                  public uint state;
                  public uint stateMask;
                  public IntPtr pszText;
                  public int cchTextMax;
                  public int iImage;
                  public IntPtr lParam;
              }
      
              const int LVM_FIRST = 0x1000;
              const int LVM_GETSELECTEDCOUNT = 4146;
              const int LVM_GETNEXTITEM = LVM_FIRST + 12;
              const int LVNI_SELECTED = 2;
              const int LVM_GETITEMCOUNT = LVM_FIRST + 4;
              const int LVM_GETITEM = LVM_FIRST + 75;
              const int LVIF_TEXT = 0x0001;
      
              [DllImport("user32.dll", EntryPoint = "GetShellWindow")]
              public static extern System.IntPtr GetShellWindow();
      
              [DllImport("user32.dll", SetLastError = true)]
              public static extern IntPtr FindWindowEx(IntPtr parentHandle, IntPtr childAfter, string className, string windowTitle);
      
              [DllImport("user32.dll", EntryPoint = "SendMessage", CharSet = CharSet.Auto)]
              public static extern int SendMessagePtr(IntPtr hWnd, int wMsg, IntPtr wParam, IntPtr lParam);
      
              [DllImport("User32.DLL")]
              public static extern int SendMessage(IntPtr hWnd, UInt32 Msg, Int32 wParam, Int32 lParam);
      
      
              public int SelectedItemCount
              {
                  get
                  {
                      return SendMessage(ShellListViewHandle, LVM_GETSELECTEDCOUNT, IntPtr.Zero.ToInt32(), IntPtr.Zero.ToInt32());
                  }
              }
              public int Count
              {
                  get
                  {
                      return SendMessage(ShellListViewHandle, LVM_GETITEMCOUNT, IntPtr.Zero.ToInt32(), IntPtr.Zero.ToInt32());
                  }
              }
              public string GetItemText(int idx)
              {
                  // Declare and populate the LVITEM structure
                  LVITEM lvi = new LVITEM();
                  lvi.mask = LVIF_TEXT;
                  lvi.cchTextMax = 512;
                  lvi.iItem = idx;            // the zero-based index of the ListView item
                  lvi.iSubItem = 0;         // the one-based index of the subitem, or 0 if this
                  //  structure refers to an item rather than a subitem
                  lvi.pszText = Marshal.AllocHGlobal(512);
      
                  // Send the LVM_GETITEM message to fill the LVITEM structure
                  IntPtr ptrLvi = Marshal.AllocHGlobal(Marshal.SizeOf(lvi));
                  Marshal.StructureToPtr(lvi, ptrLvi, false);
                  try
                  {
                      SendMessagePtr(ShellListViewHandle, LVM_GETITEM, IntPtr.Zero, ptrLvi);
                  }
                  catch (Exception ex)
                  {
                      System.Diagnostics.Debug.WriteLine(ex.Message);
                  }
      
                  // Extract the text of the specified item
                  string itemText = Marshal.PtrToStringAuto(lvi.pszText);
                  return itemText;
              }
      
              IntPtr ShellListViewHandle
              {
                  get
                  {
                      IntPtr _ProgMan = GetShellWindow();
                      IntPtr _SHELLDLL_DefViewParent = _ProgMan;
                      IntPtr _SHELLDLL_DefView = FindWindowEx(_ProgMan, IntPtr.Zero, "SHELLDLL_DefView", null);
                      IntPtr _SysListView32 = FindWindowEx(_SHELLDLL_DefView, IntPtr.Zero, "SysListView32", "FolderView");
                      return _SysListView32;
                  }
              }
      
              public int GetSelectedItemIndex(int iPos = -1)
              {
                  return SendMessage(ShellListViewHandle, LVM_GETNEXTITEM, iPos, LVNI_SELECTED);
              }
          }
      

      【讨论】:

      • 它返回项目数和选定项目数,但在 GetItemText 上崩溃,知道吗?
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-10
      相关资源
      最近更新 更多