如何获得运行过程的完整路径?

我有一个正在更改其他应用程序的某些设置的应用程序(它是一个简单的C#应用​​程序,通过双击运行(无需设置))。

更改设置后,我需要重新启动其他应用程序,以便它反映更改的设置。

所以要做,我必须杀死正在运行的进程并再次启动进程,但问题是杀死后我无法找到进程。 (原因是系统不知道exe文件在哪里..)

有没有办法找出运行进程或exe的路径,如果它正在运行?

我不想手动给路径,即如果它正在运行获取路径,杀死进程并再次启动….我将稍后处理

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

这个API有一个问题,如果您在32位应用程序中运行此代码,您将无法访问64位应用程序路径,因此您必须编译并运行您的应用程序作为64位应用程序(项目属性→构建→平台目标→x64)。

你可以做的是使用WMI来获取路径。 这将允许您获取路径,无论它是32位还是64位应用程序。 这是一个展示如何获得它的示例:

 // include the namespace using System.Management; var wmiQueryString = "SELECT ProcessId, ExecutablePath, CommandLine FROM Win32_Process"; using (var searcher = new ManagementObjectSearcher(wmiQueryString)) 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 = (string)mo["ExecutablePath"], CommandLine = (string)mo["CommandLine"], }; foreach (var item in query) { // Do what you want with the Process, Path, and CommandLine } } 

请注意,您必须引用System.Management.dll程序集并使用System.Management命名空间。

有关您可以从这些进程中获取的其他信息(例如用于启动程序的命令行( CommandLine ))的更多信息,请参阅Win32_Process类和WMI .NET以获取更多信息。

我猜你已经有了正在运行的进程的进程对象(例如,通过GetProcessesByName())。 然后,您可以使用获取可执行文件名

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

通过结合Sanjeevakumar Hiremath和Jeff Mercado的答案,您可以在某种程度上解决在32位进程中从64位进程中检索图标时的问题。

 using System; using System.Management; using System.Diagnostics; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { int processID = 6680; // Change for the process you would like to use Process process = Process.GetProcessById(processID); string path = ProcessExecutablePath(process); } static private string ProcessExecutablePath(Process process) { try { return process.MainModule.FileName; } catch { string 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.ToString() == process.Id.ToString()) { return path.ToString(); } } } return ""; } } } 

这可能有点慢,并且不适用于缺少“有效”图标的每个进程。

这是一个可靠的解决方案,适用于32位64位应用程序。

添加以下参考:

使用System.Diagnostics;

使用System.Management;

将此方法添加到您的项目:

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

现在使用它如下:

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

请注意,如果您知道进程的id,那么此方法将返回相应的ExecutePath。

额外的,对于有兴趣的人:

 Process.GetProcesses() 

…将为您提供所有当前正在运行的进程的数组,并…

 Process.GetCurrentProcess() 

…将为您提供当前流程,以及他们的信息,例如Id等,以及有限的控制,例如Kill等。*

解决方案:

  • 32位和64位进程
  • 仅限System.Diagnostics (无System.Management)

我使用了Russell Gantman的解决方案并将其重写为可以使用的扩展方法,如下所示:

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

有了这个实现:

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

您可以使用pInvoke和本机调用,如下所示。 这似乎没有32/64位限制(至少在我的测试中)

这是代码

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

尝试:

 using System.Diagnostics; ProcessModuleCollection modules = Process.GetCurrentProcess().Modules; string processpathfilename; string 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 { String fileName = process.MainModule.FileName; String 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(); } } 

Process类有一个你应该检查的成员StartInfo

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

我在寻找执行进程的当前目录时得到了这个线程。 在.net 1.1中微软介绍:

 Directory.GetCurrentDirectory(); 

似乎运行良好(但不返回进程本身的名称)。