C#:如何获取进程的可执行路径。当给定一个没有路径的文件时,Start将使用该路径?

C#:如何获取进程的可执行路径。当给定一个没有路径的文件时,Start将使用该路径?,c#,process,path,executable,processstartinfo,C#,Process,Path,Executable,Processstartinfo,System.Diagnostics.Process.Start()方法接受一个ProcessStartInfo类实例,该类实例由一个没有路径的可执行文件初始化,例如Notepad.exe。进程启动后,可以找到它使用的完整路径,例如C:\Windows\SysWOW64\notepad.exe。这是完美的,除非你想知道完整的路径而不实际启动程序。在我的例子中,我希望提前从可执行文件中获取图标 这类似于windows“where”命令的行为,例如: C:>where notepad.exe

System.Diagnostics.Process.Start()
方法接受一个
ProcessStartInfo
类实例,该类实例由一个没有路径的可执行文件初始化,例如
Notepad.exe
。进程启动后,可以找到它使用的完整路径,例如
C:\Windows\SysWOW64\notepad.exe
。这是完美的,除非你想知道完整的路径而不实际启动程序。在我的例子中,我希望提前从可执行文件中获取图标

这类似于windows“where”命令的行为,例如:

C:>where notepad.exe
C:>\Windows\System32\notepad.exe
C:>\Windows\notepad.exe

第一个响应
C:\Windows\System32\notepad.exe
基本上与“Process”使用的响应相同。如果在命令行中输入应用程序名(如notepad.exe),它将搜索当前目录以及
PATH
环境变量中指定的所有路径。当您使用
Process.Start
时,这种方法也会起到类似的作用。
因此,您需要在
PATH
环境变量的所有路径中搜索可执行文件,然后从中提取图标。

搜索路径的顺序实际上取决于注册表,因此仅通过PATH环境变量枚举不能保证产生预期结果,特别是在当前工作目录中存在预期名称的文件的情况下。为了可靠地获取可执行路径,您需要调用内核32中的Win32函数

没有任何framework.NET函数公开
SearchPath
,但是可以通过直接调用该函数

下面的示例程序说明了此函数的用法。如果系统搜索路径中存在notepad.exe,则根据系统配置,它将打印路径;如果它不存在,它将打印“未找到文件”


我相信它一定是。@Gserg,表示“SearchPath函数的搜索顺序与LoadLibrary函数使用的搜索顺序不同。”321如果REX123正确,请搜索环境变量path以查找文件。例如,请看这里:它的工作方式类似于“where”,而不是“Process.Start”,因为它返回“C:\Windows\System32\notepad.exe”,而不是“C:\Windows\SysWOW64\notepad.exe”。然而,我相信它们在功能上是等价的,而且,在任何情况下,你的回答都会对我有用。谢谢你的回答和简单的代码。
using System;
using System.Text;
using System.Runtime.InteropServices;

class Program
{
    [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
    static extern uint SearchPath(string lpPath,
         string lpFileName,
         string lpExtension,
         int nBufferLength,
         [MarshalAs ( UnmanagedType.LPTStr )]
             StringBuilder lpBuffer,
         out IntPtr lpFilePart);
    const int MAX_PATH = 260;
    public static void Main()
    {
        StringBuilder sb = new StringBuilder(MAX_PATH);
        IntPtr discard;
        var nn = SearchPath(null, "notepad.exe", null, sb.Capacity, sb, out discard);
        if (nn == 0)
        {
            var error = Marshal.GetLastWin32Error();
            // ERROR_FILE_NOT_FOUND = 2
            if (error == 2) Console.WriteLine("No file found.");
            else
                throw new System.ComponentModel.Win32Exception(error);
        }
        else
            Console.WriteLine(sb.ToString());
    }
}