2009-02-13 9 views
9

Je veux tuer un processus par programme dans Vista/Windows 7 (Je ne suis pas sûr s'il y a des problèmes importants dans l'implémentation de l'UAC entre les deux pour faire une différence) .par programme tuer un processus dans Vista/Windows 7 en C#

En ce moment, mon code ressemble à:

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); 
    } 

Je dois le faire parce que je dois faire en sorte que si l'utilisateur bloque le programme ou sort brusquement, ce processus secondaire est redémarré lorsque l'application est redémarré, ou si l'utilisateur veut changer les paramètres de ce processus secondaire.

Le code fonctionne correctement sous XP, mais il échoue dans Windows 7 (et j'imagine sous Vista) avec un message 'accès refusé'. D'après ce que le Tout-Puissant Google m'a dit, je dois gérer mon programme de meurtre en tant qu'administrateur pour contourner ce problème, mais c'est juste une sauce faible. L'autre réponse possible est d'utiliser LinkDemand, mais je ne comprends pas la page msdn de LinkDemand en ce qui concerne les processus.

Je pourrais déplacer le code dans un fil, mais cela a toute une série d'autres difficultés inhérentes à ce que je ne veux vraiment pas découvrir.

+0

Kill() semble fonctionner très bien pour moi à la fois pour les processus créés par l'explorateur et la même application. Courir Vista ici dans l'utilisateur limité. –

+0

Peut-être que c'est juste un bug de Windows 7 alors? Pouvez-vous poster votre code dans une réponse? Parce que c'est juste déconcertant pour moi. – mmr

Répondre

4

Vous avez raison, c'est parce que vous n'avez pas de privilèges administratifs. Vous pouvez résoudre ce problème en installant un service sous l'utilisateur du système local et en exécutant une commande personnalisée au besoin.

Dans vos fenêtres forment 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); 

Dans votre 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; 
    } 
} 
+0

Ceci est une solution, et probablement la bonne. Je vais devoir regarder dedans; Je n'ai aucune expérience avec les services, bien qu'il soit probablement correct de se référer à ce processus comme un service qui fonctionne à côté de l'application. – mmr

+1

C'est la seule façon que je connaisse pour accomplir ceci sans que l'utilisateur ne devienne gênant. Heureusement, vous ne devriez pas avoir à connaître quoi que ce soit sur les services (autres que l'installation de ceux-ci) afin de mettre en œuvre cela. Le modèle VS avec le code que je vous ai donné ajouté fonctionnera parfaitement. –

+0

Oui, c'est la voie à suivre. Merci pour l'aide! – mmr

0

Je vais ajouter le code pour la suggestion de Simon Buchan. Cela a du sens et devrait fonctionner aussi, en supposant que votre forme de fenêtre est ce qui a lancé le processus en premier lieu.

Voici où vous créez le processus. Notez la variable myProc. C'est votre poignée là-dessus:

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

plus tard, juste le tuer avec:

myProc.Kill(); 
+0

mais le problème est que l'application est peut-être morte inopinément, ou que l'utilisateur était agressif avec le meurtre lui-même. Je veux que le processus supprime simplement les autres instances du processus démarré par une autre instance de l'application. – mmr

+1

Ensuite, l'approche de service est probablement votre meilleure solution (seulement?). –

Questions connexes