Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/272.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 查找用于在Windows上打开特定文件类型的默认应用程序_C#_.net_Windows_File Type - Fatal编程技术网

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

C# 查找用于在Windows上打开特定文件类型的默认应用程序,c#,.net,windows,file-type,C#,.net,Windows,File Type,我正在使用C#开发一个针对.NET Framework 2.0的应用程序,我需要能够找到用于打开特定文件类型的默认应用程序 我知道,例如,如果您只想使用该应用程序打开一个文件,您可以使用以下方法: System.Diagnostics.Process.Start( "C:\...\...\myfile.html" ); 在默认浏览器中打开HTML文档,或 System.Diagnostics.Process.Start( "C:\...\...\myfile.txt" ); 在默认文本编辑器

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

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

System.Diagnostics.Process.Start( "C:\...\...\myfile.html" );
在默认浏览器中打开HTML文档,或

System.Diagnostics.Process.Start( "C:\...\...\myfile.txt" );
在默认文本编辑器中打开文本文件

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


我猜有一些Win32 API我需要p/调用才能做到这一点,但是快速浏览一下Google和MSDN并没有发现任何有趣的东西;我确实找到了大量完全不相关的页面,但没有找到我想要的

您可以在注册表部分
HKEY_CLASSES_ROOT
下查看扩展和操作详细信息。这方面的文档是。或者,您也可以使用该界面。

代码示例在VB.net中,但是将它们移植到C#应该很容易。

您可以只查询注册表。首先获取HKEY_CLASSES_ROOT\.ext下的默认条目

这将为您提供类名。例如.txt的默认值为txtfile

然后打开HKEY\U CLASSES\U ROOT\txtfile\Shell\open\Command

这将为您提供使用的默认命令。

Doh!当然

HKEY_CLASSES_ROOT\.txt
包括对

HKEY_CLASSES_ROOT\txtfile
其中包含一个子键

HKEY_CLASSES_ROOT\txtfile\shell\open\command
它引用了记事本

好的,非常感谢


Bart

目前所有的答案都不可靠。注册表是一个实现细节,事实上,在我的Windows8.1机器上,这样的代码已经被破坏了。正确的方法是使用Win32 API,特别是:

相关文档:

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();
}
示例用法:

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();
}
答案很晚,但有一个处理文件关联的好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());
    }
}

我冒昧地将代码转换为C#,并对其进行了一些修改:在我看来,FindExecutable的使用是一种更好的方式:这被否决了,但对我来说效果很好,只是做了一个小的修改(在上面编辑)。您需要“使用System.Runtime.InteropServices”。我找不到枚举,所以从MSDN:和中复制了它们。为了始终访问文本编辑器,我用AssocStr.AssocStr_EXECUTABLE和“.txt”调用了这个方法。我非常喜欢并欣赏这个答案,但我也很难找到AssocF和AssocStr的参考。我最终在另一个堆栈溢出上找到了这些标志的实现答案:向上投票,谢谢!可执行文件不适用于像.png这样的图像扩展。如何解析他们的容器应用程序?我今天遇到了这个问题,遇到了@IngoB与.png扩展名相同的问题。区别似乎源于扩展是由“完整”EXE还是UWP(这仍然是他们所说的,对:)应用程序处理的。。。例如,在我的例子中,.png是由Photos应用程序处理的,因此当
AssocStr.Executable
将失败时,请求
AssocStr.AppId
将返回
Microsoft.Windows.Photos_8wekyb3d8bbwe!应用程序
。然后,可以使用与以下答案类似的代码运行此操作:@pwrigshihanomoronimo谢谢,修复了WayBack机器链接,并向MS提交了关于坏链接的反馈(在您提到的文档中单击
ASSOCF
时,我被引导到另一个枚举)。这是
%SystemRoot%\system32\NOTEPAD.EXE%1
。这不是我的默认程序。此外,您不能使用
进程。由于
%SystemRoot%
文本和
%1
的原因,请从此进程开始。所有这些都需要在您的代码中进行特殊处理,而这些处理不能完全覆盖&这是肯定的,因为谁知道在这样的字符串中还可以期待什么。