打开资源管理器窗口,Process.Start会产生过多的explorer.exe进程。

问题描述 投票:0回答:1

当我启动一个带有目录路径的资源管理器窗口时,会生成一个新的explorer.exe进程。 在我的程序退出后,explorer.exe进程保持打开状态,这是好的,但当我关闭该explorer窗口时,该进程并没有关闭。 如果我在程序中生成了多个资源管理器窗口,那么即使关闭了所有的资源管理器窗口,也会有许多explorer.exe进程留在周围。

ProcessStartInfo startInfo = new ProcessStartInfo("explorer.exe", folderPath);
Process.Start(startInfo);

enter image description here

然而,如果我只启动explorer.exe,而没有第二个参数,那么即使打开了一个explorer窗口,也不会创建一个额外的explorer.exe进程。当那个explorer窗口被关闭时,除了桌面进程之外,你也不会看到任何额外的explorer.exe进程。 请注意,我的桌面explorer.exe的PID是7704是这个例子,应该是唯一运行的。

ProcessStartInfo startInfo = new ProcessStartInfo("explorer.exe", folderPath);
Process.Start(startInfo);

enter image description here

我发现,如果我使用cmd.exe手动做这个启动,也是如此。 在命令提示符中,如果运行 "explorer.exe C:",可以创建这个同样 "悬空 "的explorer.exe进程,而只运行 "explorer.exe "则不会。

所以我的问题是,如何才能在不创建所有这些额外的explorer.exe进程的情况下,为我想要的文件夹打开一个explorer窗口。 我也想知道这些 "悬而未决 "的explorer.exe进程是否会最终自行消失,或者它们会坐在那里占用所有内存,直到我不得不强制结束任务。 到目前为止,我已经看到它们持续存在了好几天,而且永远不会消失,即使在关闭窗口后没有与它们相关联的资源管理器窗口了。

到目前为止,我唯一能想到的就是打开一个没有参数的explorer.exe,这样它就不会创建额外的进程,然后想办法找到那个打开的explorer窗口句柄,然后用它浏览到我想要的目录。 我见过一些DLLImport("user32.dll"),也许可以做到这一点。

这听起来比直接使用Process.Start来马上到达我想要的文件夹要困难得多。 我只是不认为我的程序留下大量消耗内存的进程是个好主意,尽管你已经可以用cmd.exe做这件事了。 我不知道这是不是Windows的一个 "功能",最终会出现内存不足的情况。

c# windows directory process explorer
1个回答
0
投票

这里有一个解决方案,它不会创建额外的explorer.exe进程,而是使用现有的进程。

我是在用命令壳打开文件夹时意识到这一点的。当运行 "explorer c:\temp "时,会创建一个新的explorer.exe进程。但是当运行 "explorer c:\temp "时,会创建一个新的explorer.exe。"start c:\temp"..

所以下面的代码启动了一个隐藏的cmd进程,并将其输入与 "start <folder>\r\n""exit\r\n" 后关闭它。代码还检查新的cmd进程是否被泄露。

希望能帮到你。

Process cmd = new Process()
{
    StartInfo = new ProcessStartInfo()
    {
        FileName = "cmd",
        CreateNoWindow = true,
        UseShellExecute = false,
        RedirectStandardInput = true
    }
};
cmd.Start();
int processId = cmd.Id;
Debug.WriteLine("PID: {0}", processId);
cmd.StandardInput.Write("start " + folderPath + "\r\n");
cmd.StandardInput.Write("exit\r\n");
cmd = null;

try
{
    Process isCmdStillThere = Process.GetProcessById(processId);
}
catch (Exception errorQueryingProcess)
{
    Debug.Assert(errorQueryingProcess.Message == "Process with an Id of " + processId + " is not running.");
}
© www.soinside.com 2019 - 2024. All rights reserved.