C#:如何获得Process.Start在给定没有路径的文件时将使用的可执行路径?

时间:2015-10-27 00:20:57

标签: c# process path executable processstartinfo

System.Diagnostics.Process.Start()方法接受使用没有路径的可执行文件初始化的ProcessStartInfo类实例,例如Notepad.exe。在流程开始后,可以找到它使用的完整路径,例如C:\Windows\SysWOW64\notepad.exe。这是完美的,除非您想要在不实际启动程序的情况下了解完整路径。就我而言,我希望提前从可执行文件中获取图标。

这类似于Windows的行为"其中"命令,例如:

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

第一个回复C:\Windows\System32\notepad.exe与"过程"使用的回复基本相同。

2 个答案:

答案 0 :(得分:3)

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

没有框架.NET函数公开SearchPath,但可以通过P/Invoke直接调用该函数。

以下示例程序说明了此功能的用法。如果系统搜索路径中存在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());
    }
}

答案 1 :(得分:1)

如果在命令行中输入应用程序名称(如notepad.exe),它将在当前目录和PATH环境变量中指定的所有路径中进行搜索。使用Process.Start时,此功能类似。 因此,您需要在PATH环境变量的所有路径中搜索可执行文件,然后从中提取图标。