C #: Comment obtenir le chemin complet du processus en cours d’exécution?

J’ai une application qui modifie certains parameters d’une autre application (il s’agit d’une application C # simple qui s’exécute en double-cliquant (pas d’installation requirejse)).

Après avoir modifié les parameters, je dois redémarrer l’autre application pour qu’elle reflète les parameters modifiés.

Donc, pour faire, je dois tuer le processus en cours et recommencer le processus, mais le problème, c’est qu’après avoir tué, je ne suis pas capable de trouver le processus. (Raison est que le système ne sait pas où le fichier exe est ..)

Est-il possible de trouver le chemin du processus en cours ou de l’exécutable, s’il est en cours d’exécution?

Je ne veux pas donner le chemin manuellement, c’est-à-dire que s’il est en marche, obtenir le chemin, tuer le processus et recommencer encore

using System.Diagnostics; var process = Process.GetCurrentProcess(); // Or whatever method you are using ssortingng fullPath = process.MainModule.FileName; //fullPath has the path to exe. 

Il y a un problème avec cette API: si vous exécutez ce code dans une application 32 bits, vous ne pourrez pas accéder aux chemins d’application 64 bits, vous devrez donc comstackr et exécuter votre application en tant qu’application 64 bits. (Propriétés du projet -> Construire -> Cible de la plate-forme -> x64)

Ce que vous pouvez faire, c’est utiliser WMI pour obtenir les chemins. Cela vous permettra d’obtenir le chemin, quelle que soit son application 32 bits ou 64 bits. Voici un exemple démontrant comment vous pouvez l’obtenir:

 // include the namespace using System.Management; var wmiQuerySsortingng = "SELECT ProcessId, ExecutablePath, CommandLine FROM Win32_Process"; using (var searcher = new ManagementObjectSearcher(wmiQuerySsortingng)) using (var results = searcher.Get()) { var query = from p in Process.GetProcesses() join mo in results.Cast() on p.Id equals (int)(uint)mo["ProcessId"] select new { Process = p, Path = (ssortingng)mo["ExecutablePath"], CommandLine = (ssortingng)mo["CommandLine"], }; foreach (var item in query) { // Do what you want with the Process, Path, and CommandLine } } 

Notez que vous devez référencer l’assembly System.Management.dll et utiliser l’espace de noms System.Management .

Pour plus d’informations sur les autres informations que vous pouvez extraire de ces processus, telles que la ligne de commande utilisée pour démarrer le programme ( CommandLine ), consultez la classe Win32_Process et WMI .NET pour plus d’informations.

Je suppose que vous avez déjà l’object de processus du processus en cours d’exécution (par exemple, par GetProcessesByName ()). Vous pouvez ensuite obtenir le nom du fichier exécutable en utilisant

 Process p; ssortingng filename = p.MainModule.FileName; 

En combinant les réponses de Sanjeevakumar Hiremath et de Jeff Mercado, vous pouvez en quelque sorte contourner le problème lorsque vous récupérez l’icône d’un processus 64 bits dans un processus 32 bits.

 using System; using System.Management; using System.Diagnostics; namespace ConsoleApplication1 { class Program { static void Main(ssortingng[] args) { int processID = 6680; // Change for the process you would like to use Process process = Process.GetProcessById(processID); ssortingng path = ProcessExecutablePath(process); } static private ssortingng ProcessExecutablePath(Process process) { try { return process.MainModule.FileName; } catch { ssortingng query = "SELECT ExecutablePath, ProcessID FROM Win32_Process"; ManagementObjectSearcher searcher = new ManagementObjectSearcher(query); foreach (ManagementObject item in searcher.Get()) { object id = item["ProcessID"]; object path = item["ExecutablePath"]; if (path != null && id.ToSsortingng() == process.Id.ToSsortingng()) { return path.ToSsortingng(); } } } return ""; } } } 

Cela peut être un peu lent et ne fonctionne pas sur tous les processus sans icône “valide”.

Voici une solution fiable qui fonctionne avec les applications 32 bits et 64 bits .

Ajoutez ces références:

en utilisant System.Diagnostics;

en utilisant System.Management;

Ajoutez cette méthode à votre projet:

 public static ssortingng GetProcessPath(int processId) { ssortingng MethodResult = ""; try { ssortingng Query = "SELECT ExecutablePath FROM Win32_Process WHERE ProcessId = " + processId; using (ManagementObjectSearcher mos = new ManagementObjectSearcher(Query)) { using (ManagementObjectCollection moc = mos.Get()) { ssortingng ExecutablePath = (from mo in moc.Cast() select mo["ExecutablePath"]).First().ToSsortingng(); MethodResult = ExecutablePath; } } } catch //(Exception ex) { //ex.HandleException(); } return MethodResult; } 

Maintenant, utilisez-le comme ça:

 int RootProcessId = Process.GetCurrentProcess().Id; GetProcessPath(RootProcessId); 

Notez que si vous connaissez l’id du processus, cette méthode renverra le ExecutePath correspondant.

Extra pour ceux qui sont intéressés:

 Process.GetProcesses() 

… vous donnera un tableau de tous les processus en cours d’exécution, et …

 Process.GetCurrentProcess() 

… vous donnera le processus en cours, ainsi que leurs informations, par exemple Id, etc., ainsi qu’un contrôle limité, par exemple Kill, etc. *

Une solution pour:

  • Processus 32 bits ET 64 bits
  • System.Diagnostics uniquement (pas de System.Management)

J’ai utilisé la solution de Russell Gantman et l’ai réécrite comme une méthode d’extension que vous pouvez utiliser comme ceci:

 var process = Process.GetProcessesByName("explorer").First(); ssortingng path = process.GetMainModuleFileName(); // C:\Windows\explorer.exe 

Avec cette implémentation:

 internal static class Extensions { [DllImport("Kernel32.dll")] private static extern bool QueryFullProcessImageName([In] IntPtr hProcess, [In] uint dwFlags, [Out] SsortingngBuilder lpExeName, [In, Out] ref uint lpdwSize); public static ssortingng GetMainModuleFileName(this Process process, int buffer = 1024) { var fileNameBuilder = new SsortingngBuilder(buffer); uint bufferLength = (uint)fileNameBuilder.Capacity + 1; return QueryFullProcessImageName(process.Handle, 0, fileNameBuilder, ref bufferLength) ? fileNameBuilder.ToSsortingng() : null; } } 

Vous pouvez utiliser pInvoke et un appel natif tel que les suivants. Cela ne semble pas avoir la limitation 32/64 bits (au moins dans mes tests)

Voici le code

 using System.Runtime.InteropServices; [DllImport("Kernel32.dll")] static extern uint QueryFullProcessImageName(IntPtr hProcess, uint flags, SsortingngBuilder text, out uint size); //Get the path to a process //proc = the process desired private ssortingng GetPathToApp (Process proc) { ssortingng pathToExe = ssortingng.Empty; if (null != proc) { uint nChars = 256; SsortingngBuilder Buff = new SsortingngBuilder((int)nChars); uint success = QueryFullProcessImageName(proc.Handle, 0, Buff, out nChars); if (0 != success) { pathToExe = Buff.ToSsortingng(); } else { int error = Marshal.GetLastWin32Error(); pathToExe = ("Error = " + error + " when calling GetProcessImageFileName"); } } return pathToExe; } 

Essayer:

 using System.Diagnostics; ProcessModuleCollection modules = Process.GetCurrentProcess().Modules; ssortingng processpathfilename; ssortingng processmodulename; if (modules.Count > 0) { processpathfilename = modules[0].FileName; processmodulename= modules[0].ModuleName; } else { throw new ExecutionEngineException("Something critical occurred with the running process."); } 
 using System; using System.Diagnostics; class Program { public static void printAllprocesses() { Process[] processlist = Process.GetProcesses(); foreach (Process process in processlist) { try { Ssortingng fileName = process.MainModule.FileName; Ssortingng processName = process.ProcessName; Console.WriteLine("processName : {0}, fileName : {1}", processName, fileName); }catch(Exception e) { /* You will get access denied exception for system processes, We are skiping the system processes here */ } } } static void Main() { printAllprocesses(); } } 

La classe Process a un membre StartInfo que vous devez extraire:

 private void Test_Click(object sender, System.EventArgs e){ ssortingng path; path = System.IO.Path.GetDirectoryName( System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase ); Console.WriiteLine( path ); } 

Je suis arrivé à ce fil tout en recherchant le répertoire actuel d’un processus en cours d’exécution. Dans .net 1.1 Microsoft a introduit:

 Directory.GetCurrentDirectory(); 

Semble bien fonctionner (mais ne renvoie pas le nom du processus lui-même).