如何设置现有的Explorer.exe实例来选择文件?

时间:2011-11-18 12:33:49

标签: c#

我可以轻松地打开资源管理器并使用以下选项来选择文件:

string argument = @"/select, " + filePath;
System.Diagnostics.Process.Start("explorer.exe", argument);

但是,当我打开下一个文件时,我将获得一个新的资源管理器实例。这可能导致我们的用户在密集的一天结束时开放数百名探险家。

如何让它重用已经打开的资源管理器实例来选择我想要的文件?

当您右键单击选项卡并选择打开包含文件夹时,Visual Studio可以执行此操作... 提供的探索器已在同一目录中打开。它是如何做到的?

5 个答案:

答案 0 :(得分:4)

使用ExplorerBrowser对象如何embedding the Explorer window into your application?这样,当您想要显示不同的文件夹时,可以通过在另一个文件夹上调用IExplorerBrowser::BrowseToObject来继续重复使用该窗口。

尝试重新导航现有的资源管理器窗口是有问题的,因为您不知道用户在您不看时该窗口的用途。也许他们使用“文件夹”窗格转到其他文件夹,然后 boom 你刚从它们下面撕下那个文件夹并将其发送到其他地方。或许他们关闭它!打开一个新的资源管理器窗口是一种即发即弃的东西。如果您想保留对窗口的控制权,那么您需要进行更明确的控制(例如,通过上面的ExplorerBrowser)。

答案 1 :(得分:1)

派对有点迟了,但是如果要在已在资源管理器窗口中打开的文件夹中选择一个或多个文件,则可以使用shell32方法SHOpenFolderAndSelectItems执行此操作。如果存在,则该方法重新使用现有窗口,否则打开新窗口。

[DllImport("shell32.dll")]
private static extern int SHOpenFolderAndSelectItems(IntPtr pidlFolder, uint cidl, [MarshalAs(UnmanagedType.LPArray)] IntPtr[] apidl, uint dwFlags);

[DllImport("shell32.dll")]
private static extern void SHParseDisplayName([MarshalAs(UnmanagedType.LPWStr)] string name, IntPtr bindingContext, out IntPtr pidl, uint sfgaoIn, out uint psfgaoOut);

public static void ShowFileInExplorer(string folderPath, string filePath)
{
    Shell32.SHParseDisplayName(Path.GetFullPath(folderPath), IntPtr.Zero, out IntPtr folder, 0, out uint psfgaoOut);

    if (folder == IntPtr.Zero)
    {
        return;
    }

    Shell32.SHParseDisplayName(Path.GetFullPath(filePath), IntPtr.Zero, out IntPtr file, 0, out psfgaoOut);

    if (file != IntPtr.Zero)
    {
        IntPtr[] files = { file };

        Shell32.SHOpenFolderAndSelectItems(folder, (uint)files.Length, files, 0);
        Marshal.FreeCoTaskMem(file);
    }

    Marshal.FreeCoTaskMem(folder);
}

此示例仅选择一个文件,但可以轻松扩展以选择多个文件。

答案 2 :(得分:0)

您是否尝试过获取Process类的实例并始终使用该实例调用Start()方法?

Process myProcess = new Process();
string argument = @"/select, " + filePath;

myProcess.StartInfo.FileName = argument;
myProcess.Start();

答案 3 :(得分:0)

另一种方法是Win32 API方式。

StringBuilder sb = new StringBuilder(@"C:\temp\");
 hWnd = (...) // get Handle of the Explorer's address field.
SendMessage(hWnd, WM_SETTEXT, new IntPtr(sb.ToString().Length), sb) 

// Set the focus to the address field

SendMessage(hWnd, WM_SETFOCUS, IntPtr.Zero, null)
// Simulate Enter key
SendMessage(hWnd, WM_KEYDOWN, new IntPtr(VK_RETURN), null)

答案 4 :(得分:0)

出于类似目的,我使用launchkey.exe" {F4} ^ AC:\ TEMP {ENTER}"将F4密钥消息和直接当前资源管理器实例发送到c:\ TEMP文件夹。

我从右键单击shell上下文菜单项运行它:

Windows Registry Editor Version 5.00

[HKEY_CLASSES_ROOT\Directory\Background\shell\85TEMP]
"Position"="Top"
@="JUMP TO TEMP"

[HKEY_CLASSES_ROOT\Directory\Background\shell\85TEMP\command]
@="c:\\launchkey\\launchkey.exe \"{F4}^AC:\\TEMP{ENTER}\""

"跳到TEMP"显示项目名称
" 85 *"存在让我们保持其他"跳跃"我有几个。项目按键名反向排序,因此前面有数字。