C# 不可逆过程

C# 不可逆过程,c#,windows,service,C#,Windows,Service,我正在编写一个包含windows服务和GUI程序的程序,因为windows服务无法直接与windows通信 它是一个与服务器守护进程交互的程序,服务器守护进程阻止学生使用多个工作站上的一个帐户登录。(防止密码共享) GUI进程使用Windows autostart启动,并以用户权限运行。因此,用户可以轻松地终止GUI进程。这不好,因为GUI进程导致注销(和用户消息) 如何阻止用户终止进程?您不应禁止用户终止应用程序。如果服务在GUI关闭后失败,那么您应该修复服务,而不是GUI 但是,如果您真的想

我正在编写一个包含windows服务和GUI程序的程序,因为windows服务无法直接与windows通信

它是一个与服务器守护进程交互的程序,服务器守护进程阻止学生使用多个工作站上的一个帐户登录。(防止密码共享)

GUI进程使用Windows autostart启动,并以用户权限运行。因此,用户可以轻松地终止GUI进程。这不好,因为GUI进程导致注销(和用户消息)


如何阻止用户终止进程?

您不应禁止用户终止应用程序。如果服务在GUI关闭后失败,那么您应该修复服务,而不是GUI


但是,如果您真的想停止应用程序close look,因为您无法选择使用操作系统安全性来防止这种情况发生,那么技术上的答案是无法做到。这只剩下变通办法或替代方法

不受官方支持的一个解决方法是依赖于未记录的功能,您没有听到我的消息,这是:

public static class Unkillable
{
    [DllImport("ntdll.dll", SetLastError = true)]
    private static extern void RtlSetProcessIsCritical(UInt32 v1, UInt32 v2, UInt32 v3);

    public static void MakeProcessUnkillable()
    {
        Process.EnterDebugMode();
        RtlSetProcessIsCritical(1, 0, 0);
    }

    public static void MakeProcessKillable()
    {
        RtlSetProcessIsCritical(0, 0, 0);
    }
}
调用
Unkillable.MakeProcessUnkillable
后,终止进程将立即导致BSOD。这是一个非常丑陋的解决方案,但很难反对“可以在2分钟内实现”


另一种解决方法是创建一组进程,这些进程通过在一个进程死亡时重新启动来相互协作。

您可以研究rootkit风格的方法,从任务管理器中隐藏进程。这不是一个特别优雅的解决方案

GUI进程使用Windows autostart启动,并以用户权限运行。因此,用户可以轻松地终止GUI进程


这样如何:您运行GUI进程来向他们显示消息,但是您没有。然后他们可以随心所欲地终止GUI进程,而不会影响软件的主要功能。

也许您应该更好地配置网络。如果您的域设置正确,您可以设置一个与域控制器一起检查用户是否已登录的帐户,如果用户在其他地方登录,则将其注销

我假设每台电脑都设置了相应的帐户设置(即不是管理员)


登录脚本还可以执行其他操作,如设置网络共享。

您可以使用普通的C,抱歉,但移植到C并不太困难

从技术上讲,这并不能阻止用户终止进程,因为他们可以更改权限,但他们需要编写代码或使用专门设计的工具来完成此操作。任务管理器和pskill都不起作用,除非用户具有管理员权限


通过使用“服务使用备份/还原”权限获得进程的所有权,可以防止非管理员用户重新更改权限。

我最终使用了另一个RunAs程序,在登录时以管理员身份启动进程。这样做,学生们至少不会轻易地使用Taskmanager或类似工具来杀死它


我还可以实现稍后提出的方法。这样,即使学生们设法终止了这个过程,他们也不会成功。

它需要GUI/WinForms程序吗?这难道不是一个命令行程序吗?如果你能在每次进程被杀死时恢复进程并继续它的工作,我给你写了一个叫做“看门狗”的东西——两个程序在其中一个进程被杀死时互相恢复,并恢复第三个进程。阻止它的唯一方法是非常快地杀掉两个看门狗(使用代码),然后在第三个过程中手动杀掉-这对于大多数情况来说已经足够了。@YoryeNathan:实际上杀掉这种系统很容易,而且根本不需要任何代码。@Skizz,请详细说明一下?没有代码你怎么能做到这一点?@YoryeNathan:抓住SysInternals进程浏览器(从这里:)。找到进程并将其状态更改为“挂起”。一旦停赛,杀了他们。“我没听到”-哈哈!可爱的解决方案,除了BSOD部分。我个人不想在被杀时造成BSOD。我更喜欢。。。没有死。他在哪里说他不能使用操作系统安全性?我想我们真的应该建议:)@romkyns:“使用用户的权限运行”——因此用户可以杀死它。由于用户没有管理员权限,我想
EnterDebugMode
会失败吗?换句话说,没有管理员权限的应用程序不能对自己执行此操作。好的,确认
EnterDebugMode
提供进程
SeDebugPrivilege
,这是可用的最高权限。没有一个安全的系统可以为标准的用户进程提供一种获取此信息的方法。我们当然有登录脚本。但是如果学生只是插上网络线,这些都没有帮助。学生没有管理员权限。如何在用户登录时使用不同的权限启动进程?@Zulakis我相信您可以使用任务调度器来完成这一任务。将触发器设置为登录,并使用“运行方式”选项。然而,我已经用另一种方法更新了我的答案,我认为这种方法会更好。@Zulakis建议服务如何以不同的用户身份启动流程,但它也解释了这可能是个坏主意。我也考虑了你的第一个建议,但它看起来相当复杂。我使用的是:“[DllImport(“user32.dll”)]公共静态外部intexitwindowsex(intuflags,intdwreserved);exitwindowsecx(0x10,0);“我宁愿使用简单的解决方案。有没有一种简单的方法可以让程序自动启动并具有其他用户权限?@Zulakis我个人认为任务调度器方法非常简单。您需要安全地存储另一个用户的凭据,因此这项操作的容易程度是有限的。