2015-10-27 111 views
2

System.Diagnostics.Process.Start()方法接受使用不带路径的可执行文件初始化的ProcessStartInfo类实例,如Notepad.exe。过程开始后,可以找到它使用的完整路径,如C:\Windows\SysWOW64\notepad.exe。这是完美的,除非你想知道完整的路径而不实际启动程序。就我而言,我想提前从可执行文件中获取图标。C#:如何获得Process.Start在给定文件时没有路径时将使用的可执行文件路径?

这类似于窗口的行为“其中”命令,例如:

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

第一响应C:\Windows\System32\notepad.exe是基本相同的是,“处理”使用。

+0

我相信它必须是[与dll相同的搜索顺序](https://msdn.microsoft.com/en-us/library/windows/desktop/ms682586%28v=vs.85%29的.aspx#standard_search_order_for_desktop_applications)。 – GSerg

+0

@Gserg中,['SearchPath'文档】(https://msdn.microsoft.com/en-us/library/windows/desktop/aa365527(V = vs.85)的.aspx)指示“的搜索顺序'SearchPath'函数不同于'LoadLibrary'函数使用的搜索顺序。“ – drf

回答

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()); 
    } 
} 
+0

这似乎是“在哪里”,而不是像“处理工作。开始”,在它返回 “C:\ WINDOWS \ SYSTEM32 \ NOTEPAD.EXE”,而不是 “C:\ WINDOWS \ Syswow64资料\ NOTEPAD.EXE”。但是,我相信它们在功能上是等同的,并且无论如何,您的答案都适用于我。感谢您的答案和易于尝试的代码。 – rlarkin

1

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

+0

321polorex123是正确的,搜索环境变量路径的文件。举个例子看看这里:[http://stackoverflow.com/a/1429712/5356715](http://stackoverflow.com/a/1429712/5356715) – Ejaski