[英]How to open file with Process.Start if there is no associated program for the file type?
When I want to open an .ico
file using Process.Start
it throws an error System.ComponentModel.Win32Exception
and this is because there is no default program to open that file.当我想使用
Process.Start
打开一个.ico
文件时,它会抛出一个错误System.ComponentModel.Win32Exception
,这是因为没有打开该文件的默认程序。 I need to show the window to select the default program instead of throwing exception.我需要显示 window 到 select 默认程序而不是抛出异常。 How can I do that?
我怎样才能做到这一点?
private void btnOpenFile_Click(object sender, EventArgs e)
{
Process.Start(txtSavedAs.Text);
}
What you want to do is pinvoke the AssocQueryString
API.你想要做的是
AssocQueryString
API。 Documentation here . 文档在这里。
I use that API to get a command string associated with a shell verb.我使用该 API 来获取与 shell 动词关联的命令字符串。 So, for example, if I use the
.txt
extension, it would return:因此,例如,如果我使用
.txt
扩展名,它将返回:
C:\Windows\system32\NOTEPAD.EXE %1
Now we know that shell knows what program to execute and how to pass in the command-line argument for that specific extension.现在我们知道 shell 知道要执行什么程序以及如何为该特定扩展传递命令行参数。
So, if there is a "Command" associated with that extension, it is safe to assume shell will know how to execute that type of file;因此,如果有与该扩展名关联的“命令”,则可以安全地假设 shell 将知道如何执行该类型的文件; Hence we should be able to use ShellExecute normally.
因此我们应该能够正常使用 ShellExecute。
If there is no "Command" associated with that file extension, we will show the "openas" dialog allowing the user to pick the application they want to open the file.如果没有与该文件扩展名关联的“命令”,我们将显示“openas”对话框,允许用户选择他们想要打开文件的应用程序。
Here is a class I put together to do that work:这是我为完成这项工作而组装的 class:
AppAssociation.cs 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;
}
}
You would call this like so:你会这样称呼它:
AppAssociation.StartProcessForFile(new FileInfo(@"c:\MyFiles\TheFile.txt"));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.