программно убить процесс в Vista / Windows 7 в C # - PullRequest
9 голосов
/ 13 февраля 2009

Я хочу завершить процесс программным способом в 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) с сообщением «доступ запрещен». Судя по тому, что всемогущий Google сказал мне, мне нужно запустить мою программу убийств как администратор, чтобы обойти эту проблему, но это всего лишь слабый соус. Другой потенциальный ответ - использовать LinkDemand, но я не понимаю страницу msdn для LinkDemand, поскольку она относится к процессам.

Я мог бы переместить код в поток, но у него есть целый ряд других трудностей, присущих ему, которые я действительно не хочу открывать.

Ответы [ 2 ]

4 голосов
/ 13 февраля 2009

Вы правы, потому что у вас нет административных привилегий. Это можно решить, установив службу под пользователем локальной системы и выполнив для нее пользовательскую команду при необходимости.

В вашем приложении Windows Form:

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;
    }
}
0 голосов
/ 13 февраля 2009

Я добавлю код для предложения Саймона Бьюкена. Это имеет смысл и должно работать, если исходить из того, что именно ваша форма Windows и запустила процесс.

Здесь вы создаете процесс. Обратите внимание на переменную myProc. Вот ваша ручка:

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

Позже, просто убей его:

myProc.Kill();
...