2015-10-27 108 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