查找在Windows上打开特定文件类型的默认应用程序

Bar*_*ead 52 .net c# windows file-type

我正在使用C#开发一个面向.NET Framework 2.0的应用程序,我需要能够找到用于打开特定文件类型的默认应用程序.

我知道,例如,如果您只想使用该应用程序打开文件,您可以使用以下内容:

System.Diagnostics.Process.Start( "C:\...\...\myfile.html" );
Run Code Online (Sandbox Code Playgroud)

在默认浏览器中打开HTML文档,或

System.Diagnostics.Process.Start( "C:\...\...\myfile.txt" );
Run Code Online (Sandbox Code Playgroud)

在默认文本编辑器中打开文本文件.

但是,我希望能够在默认文本编辑器中打开不一定具有.txt扩展名的文件(例如),因此我需要能够找到打开的默认应用程序. txt文件,这将允许我直接调用它.

我猜测有一些Win32 API,我需要P/Invoke才能做到这一点,但是对谷歌和MSDN的快速浏览并没有发现任何有趣的东西; 我确实找到了大量完全不相关的页面,但没有像我在寻找的那样.

Oha*_*der 68

目前所有答案都不可靠.注册表是一个实现细节,实际上这些代码在我的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
}
Run Code Online (Sandbox Code Playgroud)

相关文件:

样品用法:

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();
}
Run Code Online (Sandbox Code Playgroud)

  • 这是一个低调投票,但只是一个小修复(上面编辑)对我来说很好.你需要"使用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"调用了此方法. (3认同)
  • 我非常喜欢并欣赏这个答案,但我也很难找到AssocF和AssocStr的参考资料.我最终在另一个堆栈上找到了这些标志的实现溢出答案:http://stackoverflow.com/questions/770023/how-do-i-get-file-type-in​​formation-based-on-extention-not-mime- in-c-sharp Upvoted,谢谢! (3认同)
  • AssocStr.Executable 不适用于 .png 等图像扩展名。您如何解决他们的容器应用程序? (3认同)
  • 我今天遇到了这个问题,并且遇到了 @IngoB 与 .png 扩展名相同的问题。差异似乎源于扩展是由“完整”EXE 还是 UWP(这仍然是它们的名称,对吧:)应用程序处理...例如,在我的例子中,.png 是由照片应用程序,因此虽然“AssocStr.Executable”会失败,但请求“AssocStr.AppId”会返回“Microsoft.Windows.Photos_8wekyb3d8bbwe!App”。然后可以使用类似于此答案的代码运行:/sf/answers/2933428151/ (2认同)

cur*_*isk 18

您可以在注册表部分中HKEY_CLASSES_ROOT查看扩展和操作详细信息.有关此文档的文档位于MSDN上.或者,您可以使用IQueryAssociations接口.


Bar*_*ead 9

卫生署!当然.

HKEY_CLASSES_ROOT\.txt
Run Code Online (Sandbox Code Playgroud)

包括对...的引用

HKEY_CLASSES_ROOT\txtfile
Run Code Online (Sandbox Code Playgroud)

其中包含一个子项

HKEY_CLASSES_ROOT\txtfile\shell\open\command
Run Code Online (Sandbox Code Playgroud)

其中引用了记事本.

排序,非常感谢!

巴特


xsl*_*xsl 5

这是一篇关于此主题的博客文章.代码示例在VB.net中,但是将它们移植到C#应该很容易.

  • 我冒昧地将该代码转换为 C# 并对其进行了一些修改:http://stackoverflow.com/a/17773554/67824 (2认同)