【问题标题】:programmatically kill a process in vista/windows 7 in C#在 C# 中以编程方式杀死 vista/windows 7 中的进程
【发布时间】:2010-10-07 09:05:12
【问题描述】:

我想在 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 页面,因为它与进程有关。

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

【问题讨论】:

  • Kill() 对于资源管理器和同一个应用程序创建的进程似乎对我来说都很好。在受限用户中运行 Vista。
  • 也许这只是 Windows 7 的错误?您可以在答案中发布您的代码吗?因为这让我很困惑。

标签: c# windows-vista process kill


【解决方案1】:

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

在您的 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;
    }
}

【讨论】:

  • 这是一个解决方案,而且可能是正确的。我得调查一下;我没有使用服务的经验,尽管将此过程称为与应用程序一起运行的服务可能是正确的。
  • 这是我所知道的唯一一种在不让用户收到烦人的 UAC 提示的情况下完成此任务的方法。幸运的是,您不必了解任何有关服务的信息(除了安装服务)即可实现这一点。带有我给您添加的代码的 VS 模板将完美运行。
  • 是的,这是要走的路。感谢您的帮助!
【解决方案2】:

我将为 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();

【讨论】:

  • 但问题是,应用程序可能意外死机,或者用户主动杀死自己。我希望该进程仅删除由另一个应用程序实例启动的进程的其他实例。
  • 那么服务方式可能是你最好的(唯一的?)解决方案。
猜你喜欢
  • 1970-01-01
  • 2011-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-17
相关资源
最近更新 更多