c# Process.Start()处理线程资源失败



程序代码如下:

using System.Diagnostics;
class Test
{
    static void Main()
    {
        using (Process p = Process.Start("notepad.exe"))
        {
        }
    }
}

问题是当这个程序已经关闭,记事本仍在运行,记事本将锁定它。我不想关闭记事本。
我尝试使用解锁器来检测问题。
结果屏幕截图如下所示:

结果图像链接

所以我想要的是启动一个exe文件,并立即处置所有线程资源。或者我不能卸载我的程序,直到它打开的所有程序被关闭。这可能会导致不愉快的用户体验。要求系统重新启动也令人不快。Unlocker可以很好地做到这一点。如果我使用Unlocker来解锁父文件夹,它不会关闭记事本,然后我可以正常删除这个程序文件

问题是您从未关闭正在运行的进程,因此它继续运行,这导致Unlocker指示它已锁定。

我知道你认为是你做的,因为你调用了p.Close(),但技巧是Process.Close()方法不会而不是导致进程关闭。它不发送WM_CLOSEWM_QUIT消息到记事本窗口。它所做的只是释放与进程相关的资源。

相反,您需要使用Process.CloseMainWindow()方法。这将发送一个WM_CLOSE消息,导致窗口正确关闭。

所以更新你的代码看起来像这样(正如其他人提到的,如果你已经在using语句中包装了对象创建,就没有必要显式调用Dispose):

using System.Diagnostics;
class Test
{
    static void Main()
    {
        using (Process p = Process.Start("notepad.exe"))
        {
            p.CloseMainWindow();
            p.Close();
        }
    }
}
请注意,您可以使用Process.Kill()方法,但这就像通过从墙上撕下电源线来关闭计算机一样。它不是要求应用程序很好地关闭,而是强制它终止,就像在任务管理器中单击"结束任务"一样。因此,只有当进程被锁定或没有响应礼貌的关闭请求时,才应该使用它。

同样,正如Rolice在注释中提到的,上面的代码不会很有用。你只是在启动记事本,然后立即关闭它。

相反,您可能希望启动进程,允许用户与之交互,然后在用户完成后进行清理。

在这种情况下,需要使用Process.WaitForExit()方法。此方法将阻塞调用线程,无限期地等待进程退出。当用户最终关闭记事本时,控制将返回到你的应用程序线程,你可以调用p.Close()

例如:

using System.Diagnostics;
class Test
{
    static void Main()
    {
        using (Process p = Process.Start("notepad.exe"))
        {
            p.WaitForExit();
            p.Close();
        }
    }
}

这里有两种可能的解决方案

  1. 在你的应用程序中,在你退出应用程序之前等待进程退出。有几种方法可以做到这一点。
  2. 在应用程序退出时终止进程。无论是好还是强制,后者都不是很好,如果用户正在编辑某些内容,可能会导致数据丢失。

在上面的情况#1中,你可以弹出一个对话框或其他东西告诉用户你正在等待记事本退出(也许有一个按钮来杀死它)

尝试在没有引用的情况下启动进程:

Process.Start("notepad.exe");

最新更新