如何在 C# 中制作未封闭的应用程序?我想禁用表单的“X”按钮并阻止 Windows 任务管理器关闭它。
我知道防止表单关闭的一种方法是处理FormClosing
事件,但是如何防止任务管理器关闭它呢?
如何在 C# 中制作未封闭的应用程序?我想禁用表单的“X”按钮并阻止 Windows 任务管理器关闭它。
我知道防止表单关闭的一种方法是处理FormClosing
事件,但是如何防止任务管理器关闭它呢?
不,无法阻止任务管理器关闭您的应用程序。任务管理器可以强制终止一个没有响应的进程;它不需要应用程序的许可来关闭它,它也不会很好地询问。(有关任务管理器的更多信息,以及可以关闭应用程序的不同方式之间的比较,请参阅此答案。)
唯一可以想到的解决方法是有两个进程,每个进程都配置为检测另一个进程何时关闭并启动一个新实例。当然,这仍然不会阻止其中一个进程被杀死,它只会允许您重新启动它。这可能属于用户敌对行为的范畴。如果我使用任务管理器关闭您的应用程序,我可能希望它消失,无论您作为程序员的意图是什么。如果它不断启动新进程,我肯定会生气(我的病毒扫描程序也可能会生气,因为它以前见过这种行为)。
我建议您重新考虑您的应用程序的设计。如果您需要在后台一直运行的东西,您应该创建一个 Windows 服务。当然,服务没有用户界面,您的应用程序似乎需要一个。所以更好的是,防御性地编写代码:保存应用程序的状态,以便可以随意关闭和恢复它。您必须处理计算机关闭的情况,那么仅处理您的应用程序被关闭有多难?
正如微软的Raymond Chen会告诉你的那样,Windows 没有这样的机制,因为没有人能想象到一个应用程序和你的应用程序一样棒,没有用户愿意关闭。
至于禁用表单的关闭框、系统/窗口菜单中的关闭图标和Alt+F4击键,这相对简单。您需要覆盖表单的CreateParams
属性,并设置CS_NOCLOSE
窗口类样式:
protected override CreateParams CreateParams
{
get
{
const int CS_NOCLOSE = 0x200;
CreateParams cp = base.CreateParams;
cp.ClassStyle |= CS_NOCLOSE;
return cp;
}
}
编译并运行。你会得到一个看起来像这样的表单(注意标题栏上禁用的关闭按钮以及系统/窗口菜单中没有“关闭”菜单项):
请注意,执行此操作时,您应该在应用程序界面中提供一种替代机制来关闭表单。例如,在显示此对话框的“主”表单上。
你永远不应该做这样的事情,但如果你真的需要这个,你应该创建一个服务。
这不是问题的答案,但我认为指出创建用户必须竭尽全力才能终止的应用程序并不总是无效的可能很重要。对于旨在在公司拥有的机器上运行并由使用该应用程序作为员工工作的公司员工操作的内部私有应用程序的情况,强制该应用程序始终保持运行是完全合法的. @TvmMurthy 问题似乎正在处理这种情况。
在我自己的工作中,MS Outlook 作为我工作站的启动应用程序之一启动,我让它运行一整天,直到我重新启动机器为止。我还编写了 Windows 窗体应用程序,让我了解我负责在我们的某些服务器上监控的进程的状态。我编写这些应用程序是为了始终保持运行,并且仅在检测到我需要了解的内容时才显示为弹出窗口(它们最小化到工具栏以防止它们妨碍它们)。我使用SharpReader为了跟上我的 RSS 提要,它自然设计为不断运行。即使您单击红色的 X,它也会最小化到工具栏,并且只能通过工具栏中的上下文菜单或使用任务管理器来终止——考虑到它的功能,这是完全合理的,甚至是预期的!
开发人员不应假设所有应用程序都是由用户自愿安装和使用的,这些用户可以自由运行他们想要的任何软件以及何时想要使用它,或者他们自己的偏好决定了行业或其他用户。管理应用程序行为的是业务需求,而不是开发人员的偏见。作为一名在行业工作的开发人员,我被要求将许多行为写入软件,如果我是为自己编写软件,我不会编写这些行为。
因为您不喜欢用户被明确指示在他或她的应用程序中设计的内容而对问题投反对票,这显示出一种不值得特别称赞的小气或狭隘。赞成的问题来抵消这一点。
保护一个进程不被普通用户杀死并不难。应用程序可以修改它自己的进程 ACL,防止任何任务管理器杀死它。他们只会得到“拒绝访问!” 当试图杀死进程时。
但是,您应该始终允许管理员能够终止该进程,这样它就不会干扰系统关闭或其他管理任务。
如果仍然需要,我可以为您提供代码。