簡體   English   中英

C#獲取尚未運行的Process Object的完整路徑

[英]C# get the full path of a not yet running Process Object

我目前正在嘗試完成以下任務:

對於我們提供給客戶的SDK,我們希望SDK開發人員能夠提供外部應用程序調用,以便他們可以插入其他按鈕。 然后,這些按鈕將啟動外部應用程序或使用默認應用程序打開文件(例如,Word表示* .docx)。

不同按鈕之間應該在視覺上有所區別,因此我們的方法是顯示要調用的應用程序的圖標。

現在,有三種不同類型的調用:(下面的字符串始終是ProcessStartInfo.FileName的值)

  1. 調用提供完整應用程序路徑(可能帶有環境變量)的應用程序(例如"C:\\Program Files\\Internet Explorer\\iexplore.exe" / "%ProgramFiles%\\Internet Explorer\\iexplore.exe"
  2. 如果可以在PATH變量中找到給定應用程序的名稱,則調用僅提供可執行文件名稱的應用程序(例如"iexplore"
  3. 打開文檔,但不提供打開它的應用程序(例如"D:\\test.html"

我們正在尋找一種方法,為任何給定的呼叫找到合適的圖標。 為此,我們必須找到應用程序完整應用程序路徑 ,該路徑將以上述三種方式中的任何一種執行,但是我們實際啟動流程之前


在啟動進程之前 ,是否可以找到System.Diagnostics.Process或System.Diagnostics.ProcessStartInfo對象的完整路徑或圖標?

重要提示:我們切勿在此之前開始該過程(可能會有副作用)

示例代碼:

var process = new Process
{
    StartInfo =
    {
        //applicationPath could be any of the stated above calls
        FileName = Environment.ExpandEnvironmentVariables(applicationPath)
    }
};
//we have to find the full path here, but MainModule is null as long as the process object has not yet started
var icon = Icon.ExtractAssociatedIcon(process.MainModule.FullPath) 

解決方案謝謝你們,我找到了我的解決方案。 CodeProject此處鏈接的項目為我的確切問題提供了解決方案,該解決方案可與程序和文件同等使用,並且可以在開始過程之前提供圖標。 感謝您的鏈接@wgraham

Process類可以完全滿足您的要求。 必須先使用Environment.ExpandEnvironmentVariables(string)擴展%ProgramFiles%之類的環境變量。


1。

using System.IO;
using System.Diagnostics;

string iexplore = @"C:\Program Files\Internet Explorer\iexplore.exe");

string iexploreWithEnvVars = Environment.ExpandEnvironmentVariables(@"%ProgramFiles%\Internet Explorer\iexplore.exe");

2。

public static string FindFileInPath(string name)
{
    foreach (string path in Environment.ExpandEnvironmentVariables("%path%").Split(';'))
    {
        string filename;
        if (File.Exists(filename = Path.Combine(path, name)))
        {
            return filename; // returns the absolute path if the file exists
        }
    }
    return null; // will return null if it didn't find anything
}

3。

Process.Start("D:\\test.html");

您還希望將代碼放入try-catch塊中,因為如果文件不存在,則Process.Start將引發Exception。

編輯:更新了代碼,感謝Dan Field指出我錯過了問題的含義。 :/

前兩個示例應該不難使用Environment.ExpandEnvironmentVariables 最后一個是更艱難的-最好的選擇似乎是使用PInvoke調用AssocCreate 改編自pinvoke頁面( http://www.pinvoke.net/default.aspx/shlwapi/AssocCreate.html ):

public static class GetDefaultProgramHelper
{
    public unsafe static string GetDefaultProgram(string ext)
    {
        try
        {
           object obj;
           AssocCreate(
             ref CLSID_QueryAssociations,
             ref IID_IQueryAssociations,
             out obj);
           IQueryAssociations qa = (IQueryAssociations)obj;
           qa.Init(
             ASSOCF.INIT_DEFAULTTOSTAR,
             ext, //".doc",
             UIntPtr.Zero, IntPtr.Zero);

           int size = 0;
           qa.GetString(ASSOCF.NOTRUNCATE, ASSOCSTR.COMMAND,
             "open", null, ref size);

           StringBuilder sb = new StringBuilder(size);
           qa.GetString(ASSOCF.NOTRUNCATE, ASSOCSTR.COMMAND,
             "open", sb, ref size);

           //Console.WriteLine(".doc is opened by : {0}", sb.ToString());
           return sb.ToString();
        }
        catch(Exception e)
        {
           if((uint)Marshal.GetHRForException(e) == 0x80070483)
             //Console.WriteLine("No command line is associated to .doc open verb.");
             return null;
           else
             throw;
        }
    }

    [DllImport("shlwapi.dll")]
    extern static int AssocCreate(
       ref Guid clsid,
       ref Guid riid,
       [MarshalAs(UnmanagedType.Interface)] out object ppv);

    [Flags]
    enum ASSOCF
    {
       INIT_NOREMAPCLSID = 0x00000001,
       INIT_BYEXENAME = 0x00000002,
       OPEN_BYEXENAME = 0x00000002,
       INIT_DEFAULTTOSTAR = 0x00000004,
       INIT_DEFAULTTOFOLDER = 0x00000008,
       NOUSERSETTINGS = 0x00000010,
       NOTRUNCATE = 0x00000020,
       VERIFY = 0x00000040,
       REMAPRUNDLL = 0x00000080,
       NOFIXUPS = 0x00000100,
       IGNOREBASECLASS = 0x00000200,
       INIT_IGNOREUNKNOWN = 0x00000400
    }

    enum ASSOCSTR
    {
       COMMAND = 1,
       EXECUTABLE,
       FRIENDLYDOCNAME,
       FRIENDLYAPPNAME,
       NOOPEN,
       SHELLNEWVALUE,
       DDECOMMAND,
       DDEIFEXEC,
       DDEAPPLICATION,
       DDETOPIC,
       INFOTIP,
       QUICKTIP,
       TILEINFO,
       CONTENTTYPE,
       DEFAULTICON,
       SHELLEXTENSION
    }

    enum ASSOCKEY
    {
       SHELLEXECCLASS = 1,
       APP,
       CLASS,
       BASECLASS
    }

    enum ASSOCDATA
    {
       MSIDESCRIPTOR = 1,
       NOACTIVATEHANDLER,
       QUERYCLASSSTORE,
       HASPERUSERASSOC,
       EDITFLAGS,
       VALUE
    }

    [Guid("c46ca590-3c3f-11d2-bee6-0000f805ca57"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    interface IQueryAssociations
    {
       void Init(
         [In] ASSOCF flags,
         [In, MarshalAs(UnmanagedType.LPWStr)] string pszAssoc,
         [In] UIntPtr hkProgid,
         [In] IntPtr hwnd);

       void GetString(
         [In] ASSOCF flags,
         [In] ASSOCSTR str,
         [In, MarshalAs(UnmanagedType.LPWStr)] string pwszExtra,
         [Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pwszOut,
         [In, Out] ref int pcchOut);

       void GetKey(
         [In] ASSOCF flags,
         [In] ASSOCKEY str,
         [In, MarshalAs(UnmanagedType.LPWStr)] string pwszExtra,
         [Out] out UIntPtr phkeyOut);

       void GetData(
         [In] ASSOCF flags,
         [In] ASSOCDATA data,
         [In, MarshalAs(UnmanagedType.LPWStr)] string pwszExtra,
         [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 4)] out byte[] pvOut,
         [In, Out] ref int pcbOut);

       void GetEnum(); // not used actually
    }

    static Guid CLSID_QueryAssociations = new Guid("a07034fd-6caa-4954-ac3f-97a27216f98a");
    static Guid IID_IQueryAssociations = new Guid("c46ca590-3c3f-11d2-bee6-0000f805ca57");

}

您可以使用string filePathToProgram = GetDefaultProgramHelper.GetDefaultProgram(".docx");來調用它string filePathToProgram = GetDefaultProgramHelper.GetDefaultProgram(".docx");

如果希望您的UI與用戶的其余計算機在視覺上保持一致,則可能需要使用Icon.ExtractAssociatedIcon(string path) 從文件中提取圖標 這適用於WinForms / GDI世界。 或者, 此問題解決如何使用P / Invoke完成它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM