2008-10-02 48 views
47

我正在開發一個針對.NET Framework 2.0的應用程序,使用C#,我需要能夠找到用於打開特定文件類型的默認應用程序。尋找在Windows上打開特定文件類型的默認應用程序

我知道,例如,如果你只是想使用的應用程序,你可以使用像打開一個文件:

System.Diagnostics.Process.Start("C:\...\...\myfile.html"); 

在默認瀏覽器中打開HTML文檔,或

System.Diagnostics.Process.Start("C:\...\...\myfile.txt"); 

在默認文本編輯器中打開文本文件。

不過,我希望能夠做的就是打開不一定有.TXT擴展名(例如)文件,在默認的文本編輯器,所以我需要能夠找出默認應用程序打開.txt文件,這將允許我直接調用它。

我猜這裏有一些Win32 API,我需要P/Invoke才能做到這一點,但是快速查看Google和MSDN並沒有發現任何有趣的東西;我確實發現了大量完全不相關的頁面,但沒有像我期待的那樣。

回答

17

您可以在註冊表部分HKEY_CLASSES_ROOT下查看擴展和操作的詳細信息。此文檔是on MSDN。或者,您可以使用IQueryAssociations界面。

+1

在我看來,FindExecutable的用法是更好的方法:http://stackoverflow.com/a/9540278/2427749 – 2013-07-29 15:07:12

5

Here is a blog post with about this topic.代碼示例在VB.net中,但應該很容易將它們移植到C#。

+1

我冒昧地將該代碼轉換爲C#並修改了一下:http:// stackoverflow.com/a/17773554/67824 – 2013-07-21 14:47:43

3

您可以查詢註冊表。首先獲取HKEY_CLASSES_ROOT \ .ext下的Default條目

這會給你類名。例如.TXT有txtfile

然後打開HKEY_CLASSES_ROOT默認\ txtfile \殼牌\打開\命令

這會給你使用的是默認命令。

9

Doh!當然。

HKEY_CLASSES_ROOT\.txt 

包括到

HKEY_CLASSES_ROOT\txtfile 

參考其中包含一個子項

HKEY_CLASSES_ROOT\txtfile\shell\open\command 

它引用記事本。

已排序,非常感謝!

Bart

+0

這是`%SystemRoot%\ system32 \ NOTEPAD.EXE%1`。這不是我的情況下的默認程序。另外,由於`%SystemRoot%`字面值和`%1`的原因,您不能使用`Process.Start`。所有這些都需要在你的代碼中進行特殊處理,因爲誰也不知道在這樣的字符串中可以預期到什麼,所以不能完全覆蓋和明確地覆蓋它們。 – bytecode77 2016-12-24 10:21:40

51

當前所有的答案都不可靠。註冊表是一個實現細節,而且我的Windows 8.1機器上確實存在這樣的代碼。要做到這一點,正確的方法是使用Win32 API,具體AssocQueryString

using System.Runtime.InteropServices; 

[DllImport("Shlwapi.dll", CharSet = CharSet.Unicode)] 
public static extern uint AssocQueryString(
    AssocF flags, 
    AssocStr str, 
    string pszAssoc, 
    string pszExtra, 
    [Out] StringBuilder pszOut, 
    ref uint pcchOut 
); 

[Flags] 
public enum AssocF 
{ 
    None = 0, 
    Init_NoRemapCLSID = 0x1, 
    Init_ByExeName = 0x2, 
    Open_ByExeName = 0x2, 
    Init_DefaultToStar = 0x4, 
    Init_DefaultToFolder = 0x8, 
    NoUserSettings = 0x10, 
    NoTruncate = 0x20, 
    Verify = 0x40, 
    RemapRunDll = 0x80, 
    NoFixUps = 0x100, 
    IgnoreBaseClass = 0x200, 
    Init_IgnoreUnknown = 0x400, 
    Init_Fixed_ProgId = 0x800, 
    Is_Protocol = 0x1000, 
    Init_For_File = 0x2000 
} 

public enum AssocStr 
{ 
    Command = 1, 
    Executable, 
    FriendlyDocName, 
    FriendlyAppName, 
    NoOpen, 
    ShellNewValue, 
    DDECommand, 
    DDEIfExec, 
    DDEApplication, 
    DDETopic, 
    InfoTip, 
    QuickTip, 
    TileInfo, 
    ContentType, 
    DefaultIcon, 
    ShellExtension, 
    DropTarget, 
    DelegateExecute, 
    Supported_Uri_Protocols, 
    ProgID, 
    AppID, 
    AppPublisher, 
    AppIconReference, 
    Max 
} 

相關文章:

使用範例:

static string AssocQueryString(AssocStr association, string extension) 
{ 
    const int S_OK = 0; 
    const int S_FALSE = 1; 

    uint length = 0; 
    uint ret = AssocQueryString(AssocF.None, association, extension, null, null, ref length); 
    if (ret != S_FALSE) 
    { 
     throw new InvalidOperationException("Could not determine associated string"); 
    } 

    var sb = new StringBuilder((int)length); // (length-1) will probably work too as the marshaller adds null termination 
    ret = AssocQueryString(AssocF.None, association, extension, null, sb, ref length); 
    if (ret != S_OK) 
    { 
     throw new InvalidOperationException("Could not determine associated string"); 
    } 

    return sb.ToString(); 
} 
+3

這是倒票,但只是一個小修復(上面編輯),我很好。你需要「使用System.Runtime.InteropServices」。我無法找到枚舉,所以從MSDN複製它們:[ASSOCF](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762471(v = vs.85).aspx)和[ASOCSTR](https://msdn.microsoft.com/en-us/library/windows/desktop/bb762475(v = vs.85)的.aspx)。要總是訪問文本編輯器,我用AssocStr.ASSOCSTR_EXECUTABLE和「.txt」調用了這個方法。 – Giles 2015-02-24 10:45:55

1

逾期的答案,但有是處理文件關聯了良好的NuGet包:文件關聯

Link NUGET File Association

用法很簡單,例如將所有允許的文件擴展名添加到上下文菜單中:

private void OnMenuSourceFileOpening(object sender, ...) 
{ // open a context menu with the associated files + ".txt" files 
    if (File.Exists(this.SelectedFileName)) 
    { 
     string fileExt = Path.GetExtension(this.SelectedFileNames); 
     string[] allowedExtensions = new string[] { fileExt, ".txt" }; 
     var fileAssociations = allowedExtensions 
      .Select(ext => new FileAssociationInfo(ext)); 
     var progInfos = fileAssociations 
      .Select(fileAssoc => new ProgramAssociationInfo (fileAssoc.ProgID)); 
     var toolstripItems = myProgInfos 
      .Select(proginfo => new ToolStripLabel (proginfo.Description) { Tag = proginfo }); 
     // add also the prog info as Tag, for easy access 
     // when the toolstrip item is selected 
     // of course this can also be done in one long linq statement 

     // fill the context menu: 
     this.contextMenu1.Items.Clear(); 
     this.contextMenuOpenSourceFile.Items.AddRange (toolstripItems.ToArray()); 
    } 
} 
相關問題