我使用以下代码,以便当用户单击某个按钮时,会在特定路径中打开 Windows资源管理器的实例。但这会导致打开 Explorer 的新实例。
我想更改它,以便如果 Explorer 已在同一路径中打开,程序不会创建新进程,而是将打开的实例放在前面。
private void button_Click(object sender, EventArgs e)
{
if (Directory.Exists(myPath))
Process filesFolder = Process.Start("explorer.exe", Conf.FilesLocation);
}
答案 0 :(得分:3)
您可以使用"打开"动词,它将打开资源管理器中的目录并重新使用现有的explorer.exe,如果你传递它已经打开的目录:
因此,假设 var proc = new ProcessStartInfo();
proc.FileName = Conf.FilesLocation;
proc.Verb = "open";
proc.WindowStyle = ProcessWindowStyle.Hidden;
Process.Start(proc );
是一个目录:
\u2013
答案 1 :(得分:1)
尽管@nos的答案很有效,但大多数情况下(有时,它可能会以不确定的方式创建另一个资源管理器窗口,即使它可能已经存在),但我对Process.Start(proc)
所花费的时间却不满意窗口,有时需要2到4秒。
因此,调整一些VB.NET code可以实现重用现有资源管理器窗口的快速方法,该窗口指向所需文件夹:
首先,添加COM引用:
using Shell32;//Shell32.dll for ShellFolderView
using SHDocVw;//Microsoft Internet Controls for IShellWindows
[DllImport("user32.dll")]
public static extern int ShowWindow(IntPtr Hwnd, int iCmdShow);
[DllImport("user32.dll")]
public static extern bool IsIconic(IntPtr Hwnd);
public static bool ShowInExplorer(string folderName)
{
var SW_RESTORE = 9;
var exShell = (IShellDispatch2)Activator.CreateInstance(
Type.GetTypeFromProgID("Shell.Application"));
foreach (ShellBrowserWindow w in (IShellWindows) exShell.Windows())
{
if (w.Document is ShellFolderView)
{
var expPath = w.Document.FocusedItem.Path;
if (!Directory.Exists(Path.GetDirectoryName(expPath)) ||
Path.GetDirectoryName(expPath) != folderName) continue;
if (IsIconic(new IntPtr(w.HWND)))
{
w.Visible = false;
w.Visible = true;
ShowWindow(new IntPtr(w.HWND),SW_RESTORE);
break;
}
else
{
w.Visible = false;
w.Visible = true;
break;
}
}
}
}
尽管我们对ShellFolderView对象感兴趣,并且foreach (ShellBrowserWindow w in (ShellFolderView) exShell.Windows())
更具有逻辑意义,但不幸的是ShellFolderView并未实现IEnumerable,因此,没有foreach:(
无论如何,这是一种非常快速的方法(200毫秒),用于选择并闪烁已打开的正确浏览器窗口。
答案 2 :(得分:0)
我发现也可以使用file://
协议,当你这样做时,如果文件夹已经打开,Windows似乎会关注该文件夹,而不是打开另一个窗口
Process.Start("file://" + Conf.FilesLocation);
答案 3 :(得分:0)
对我来说,这里的解决方案都不适用于 Win10。对于 Marcelo 的解决方案 exShell.Windows()
始终为空,Josh 的解决方案不适用于目录,您将收到 file does not exist
错误,而 nos 的解决方案抛出 access denied
错误。
这是我的工作解决方案:
public static void ShowInExplorer(string filePath) {
IntPtr hWnd = FindWindow("CabinetWClass", Path.GetDirectoryName(filePath));
if(hWnd != IntPtr.Zero) {
SetForegroundWindow(hWnd);
} else {
Process.Start("explorer.exe", Path.GetDirectoryName(filePath));
}
}
Windows 资源管理器具有窗口类 CabinetWClass
并将标题设置为浏览目录。
因此上面的代码检查是否存在具有特定目录的资源管理器窗口。
如果确实存在,则将窗口置于最前面,否则将使用指定目录启动一个新的 explorer 实例。请注意,您需要使用作为参数给出的路径专门开始 explorer.exe
,否则它会抛出 access denied
错误。