![](/img/trans.png)
[英]How to open a file on a network share drive with the default program using Process.Start in .NET Core 2.1
[英]How to open file with Process.Start if there is no associated program for the file type?
当我想使用Process.Start
打开一个.ico
文件时,它会抛出一个错误System.ComponentModel.Win32Exception
,这是因为没有打开该文件的默认程序。 我需要显示 window 到 select 默认程序而不是抛出异常。 我怎样才能做到这一点?
private void btnOpenFile_Click(object sender, EventArgs e)
{
Process.Start(txtSavedAs.Text);
}
你想要做的是AssocQueryString
API。 文档在这里。
我使用该 API 来获取与 shell 动词关联的命令字符串。 因此,例如,如果我使用.txt
扩展名,它将返回:
C:\Windows\system32\NOTEPAD.EXE %1
现在我们知道 shell 知道要执行什么程序以及如何为该特定扩展传递命令行参数。
因此,如果有与该扩展名关联的“命令”,则可以安全地假设 shell 将知道如何执行该类型的文件; 因此我们应该能够正常使用 ShellExecute。
如果没有与该文件扩展名关联的“命令”,我们将显示“openas”对话框,允许用户选择他们想要打开文件的应用程序。
这是我为完成这项工作而组装的 class:
AppAssociation.cs
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
public static class AppAssociation
{
private static class Win32Native
{
public const int ASSOCF_NONE = 0;
public const int ASSOCSTR_COMMAND = 1;
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode,
EntryPoint = "AssocQueryStringW")]
public static extern uint AssocQueryString(int flags, int str,
string pszAssoc, string pszExtra, StringBuilder pszOut, ref uint pcchOut);
}
public static Process StartProcessForFile(FileInfo file)
{
var command = GetCommandForFileExtention(file.Extension);
return Process.Start(new ProcessStartInfo()
{
WindowStyle = ProcessWindowStyle.Normal,
FileName = file.FullName,
Verb = string.IsNullOrEmpty(command) ? "openas" : null,
UseShellExecute = true,
ErrorDialog = true
});
}
private static string GetCommandForFileExtention(string ext)
{
// query length of the buffer we need
uint length = 0;
if (Win32Native.AssocQueryString(Win32Native.ASSOCF_NONE,
Win32Native.ASSOCSTR_COMMAND, ext, null, null, ref length) == 1)
{
// build the buffer
var sb = new StringBuilder((int)length);
// ask for the actual command string with the right-sized buffer
if (Win32Native.AssocQueryString(Win32Native.ASSOCF_NONE,
Win32Native.ASSOCSTR_COMMAND, ext, null, sb, ref length) == 0)
{
return sb.ToString();
}
}
return null;
}
}
你会这样称呼它:
AppAssociation.StartProcessForFile(new FileInfo(@"c:\MyFiles\TheFile.txt"));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.