在 C# 中以编程方式终止 vista/windows 7 中的进程

发布于 2024-07-13 10:13:33 字数 809 浏览 5 评论 0原文

我想在 vista/windows 7 中以编程方式终止一个进程(我不确定两者之间的 UAC 实现是否存在重大问题以产生影响)。

现在,我的代码如下所示:

  if(killProcess){
      System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("MyProcessName");
       // Before starting the new process make sure no other MyProcessName is running.
        foreach (System.Diagnostics.Process p in process)
        {
            p.Kill();
        }

        myProcess = System.Diagnostics.Process.Start(psi);
   }

我必须这样做,因为我需要确保如果用户使程序崩溃或突然退出,则当应用程序重新启动时,或者如果用户想要更改参数,会重新​​启动此辅助进程对于这个二次过程。

该代码在 XP 中运行良好,但在 Windows 7 中(我假设在 Vista 中)失败,并显示“访问被拒绝”消息。 根据全能的谷歌告诉我的,我需要以管理员身份运行我的杀戮程序来解决这个问题,但这只是弱酱。 另一个可能的答案是使用 LinkDemand,但我不明白 LinkDemand 的 msdn 页面,因为它与进程有关。

我可以将代码移动到一个线程中,但这有很多我真的不想发现的固有的其他困难。

I want to kill a process programmatically in vista/windows 7 (I'm not sure if there's significant problems in the implementation of the UAC between the two to make a difference).

Right now, my code looks like:

  if(killProcess){
      System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("MyProcessName");
       // Before starting the new process make sure no other MyProcessName is running.
        foreach (System.Diagnostics.Process p in process)
        {
            p.Kill();
        }

        myProcess = System.Diagnostics.Process.Start(psi);
   }

I have to do this because I need to make sure that if the user crashes the program or exits abruptly, this secondary process is restarted when the application is restarted, or if the user wants to change the parameters for this secondary process.

The code works fine in XP, but fails in Windows 7 (and I assume in Vista) with an 'access is denied' message. From what the Almighty Google has told me, I need to run my killing program as administrator to get around this problem, but that's just weak sauce. The other potential answer is to use LinkDemand, but I don't understand the msdn page for LinkDemand as it pertains to processes.

I could move the code into a thread, but that has a whole host of other difficulties inherent to it that I really don't want to discover.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

花桑 2024-07-20 10:13:33

您是对的,因为您没有管理权限。 您可以通过在本地系统用户下安装服务并根据需要对其运行自定义命令来解决此问题。

在您的 Windows 窗体应用程序中:

private enum SimpleServiceCustomCommands { KillProcess = 128 };

ServiceControllerPermission scp = new ServiceControllerPermission(ServiceControllerPermissionAccess.Control, Environment.MachineName, "SERVICE_NAME");
scp.Assert();
System.ServiceProcess.ServiceController serviceCon = new System.ServiceProcess.ServiceController("SERVICE_NAME", Environment.MachineName);
serviceCon.ExecuteCommand((int)SimpleServiceCustomCommands.KillProcess);

myProcess = System.Diagnostics.Process.Start(psi);

在您的服务中:

private enum SimpleServiceCustomCommands { KillProcess = 128 };

protected override void OnCustomCommand(int command)
{
    switch (command)
    {
        case (int)SimpleServiceCustomCommands.KillProcess:
            if(killProcess)
            {
                System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("MyProcessName");
                // Before starting the new process make sure no other MyProcessName is running.
                foreach (System.Diagnostics.Process p in process)
                {
                    p.Kill();
                }
            }
            break;
        default:
            break;
    }
}

You are correct in that it's because you don't have administrative priveleges. You can solve this by installing a service under the local system user and running a custom command against it as needed.

In your windows form app:

private enum SimpleServiceCustomCommands { KillProcess = 128 };

ServiceControllerPermission scp = new ServiceControllerPermission(ServiceControllerPermissionAccess.Control, Environment.MachineName, "SERVICE_NAME");
scp.Assert();
System.ServiceProcess.ServiceController serviceCon = new System.ServiceProcess.ServiceController("SERVICE_NAME", Environment.MachineName);
serviceCon.ExecuteCommand((int)SimpleServiceCustomCommands.KillProcess);

myProcess = System.Diagnostics.Process.Start(psi);

In your service:

private enum SimpleServiceCustomCommands { KillProcess = 128 };

protected override void OnCustomCommand(int command)
{
    switch (command)
    {
        case (int)SimpleServiceCustomCommands.KillProcess:
            if(killProcess)
            {
                System.Diagnostics.Process[] process = System.Diagnostics.Process.GetProcessesByName("MyProcessName");
                // Before starting the new process make sure no other MyProcessName is running.
                foreach (System.Diagnostics.Process p in process)
                {
                    p.Kill();
                }
            }
            break;
        default:
            break;
    }
}
一个人练习一个人 2024-07-20 10:13:33

我将根据 Simon Buchan 的建议添加代码。 假设您的 Windows 窗体是首先启动该过程的,那么这是有道理的并且应该也可以工作。

这是您创建流程的地方。 注意变量 myProc。 这就是你对它的处理:

System.Diagnostics.Process myProc = new System.Diagnostics.Process();
myProc.EnableRaisingEvents=false;
myProc.StartInfo.FileName="PATH_TO_EXE";
myProc.Start();

稍后,只需用以下命令杀死它:

myProc.Kill();

I'll add the code for Simon Buchan's suggestion. It makes sense and should work as well, assuming your windows form is what launched the process in the first place.

Here's where you create the process. Notice the variable myProc. That's your handle on it:

System.Diagnostics.Process myProc = new System.Diagnostics.Process();
myProc.EnableRaisingEvents=false;
myProc.StartInfo.FileName="PATH_TO_EXE";
myProc.Start();

Later, just kill it with:

myProc.Kill();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文