程序代码如下:
using System.Diagnostics;
class Test
{
static void Main()
{
using (Process p = Process.Start("notepad.exe"))
{
}
}
}
问题是当这个程序已经关闭,记事本仍在运行,记事本将锁定它。我不想关闭记事本。
我尝试使用解锁器来检测问题。
结果屏幕截图如下所示:
结果图像链接
所以我想要的是启动一个exe文件,并立即处置所有线程资源。或者我不能卸载我的程序,直到它打开的所有程序被关闭。这可能会导致不愉快的用户体验。要求系统重新启动也令人不快。Unlocker可以很好地做到这一点。如果我使用Unlocker来解锁父文件夹,它不会关闭记事本,然后我可以正常删除这个程序文件
问题是您从未关闭正在运行的进程,因此它继续运行,这导致Unlocker指示它已锁定。
我知道你认为是你做的,因为你调用了p.Close()
,但技巧是Process.Close()
方法不会而不是导致进程关闭。它不发送WM_CLOSE
或WM_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中,你可以弹出一个对话框或其他东西告诉用户你正在等待记事本退出(也许有一个按钮来杀死它)
尝试在没有引用的情况下启动进程:
Process.Start("notepad.exe");