获取与c#中的ProcessStartInfo一起使用的可用动词(文件关联)列表

我正在尝试使用ProcessStartInfo类打开和打印文件。 (文件可以是任何东西,但我们假设它是PDF文件)

ProcessStartInfo pi = new ProcessStartInfo(file); pi.Arguments = Path.GetFileName(file); pi.WorkingDirectory = Path.GetDirectoryName(file); pi.Verb = "OPEN"; Process.Start(pi); 

这适用于pi.Verb = "OPEN"; 。 有些应用程序也使用动词“PRINT”注册自己,但只有一些应用程序注册。 在我的情况下(Windows PDF Viewer)我尝试使用pi.Verb = "PRINT";执行时出现exceptionpi.Verb = "PRINT";

有没有办法在运行时查看C#中特定类型的所有动词?

多谢

来自MSDN: https : //msdn.microsoft.com/en-us/library/65kczb9y(v = vs.110).aspx ? cs-save-lang = 1& ct-lang = csharp#code- snippet-2

  startInfo = new ProcessStartInfo(fileName); if (File.Exists(fileName)) { i = 0; foreach (String verb in startInfo.Verbs) { // Display the possible verbs. Console.WriteLine(" {0}. {1}", i.ToString(), verb); i++; } } 

ProcessStartInfo.Verbs属性有点破碎,因为它没有考虑更新版本的Windows(Windows 8及更高版本)如何检索已注册的应用程序。 该属性仅检查为HKCR\.ext下定义的ProgId注册的动词(可在参考源中看到),并且不考虑其他位置,例如注册表项下面的HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.ext或其他一些地方,例如通过政策定义。

获得注册动词

最好的方法是不依赖于直接检查注册表(由ProcessStartInfo类完成),而是使用适当的Windows API函数AssocQueryString来检索关联的ProgId:

 using System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Linq; using System.Runtime.InteropServices; using System.Text; using Microsoft.Win32; class Program { private static void Main(string[] args) { string fileName = @"E:\Pictures\Sample.jpg"; string progId = AssocQueryString(AssocStr.ASSOCSTR_PROGID, fileName); var verbs = GetVerbsByProgId(progId); if (!verbs.Contains("printto")) { throw new Exception("PrintTo is not supported!"); } } private static string[] GetVerbsByProgId(string progId) { var verbs = new List(); if (!string.IsNullOrEmpty(progId)) { using (var key = Registry.ClassesRoot.OpenSubKey(progId + "\\shell")) { if (key != null) { var names = key.GetSubKeyNames(); verbs.AddRange( names.Where( name => string.Compare( name, "new", StringComparison.OrdinalIgnoreCase) != 0)); } } } return verbs.ToArray(); } private static string AssocQueryString(AssocStr association, string extension) { uint length = 0; uint ret = AssocQueryString( AssocF.ASSOCF_NONE, association, extension, "printto", null, ref length); if (ret != 1) //expected S_FALSE { throw new Win32Exception(); } var sb = new StringBuilder((int)length); ret = AssocQueryString( AssocF.ASSOCF_NONE, association, extension, null, sb, ref length); if (ret != 0) //expected S_OK { throw new Win32Exception(); } return sb.ToString(); } [DllImport("Shlwapi.dll", CharSet = CharSet.Unicode, SetLastError = true)] private static extern uint AssocQueryString( AssocF flags, AssocStr str, string pszAssoc, string pszExtra, [Out] StringBuilder pszOut, ref uint pcchOut); [Flags] private enum AssocF : uint { ASSOCF_NONE = 0x00000000, ASSOCF_INIT_NOREMAPCLSID = 0x00000001, ASSOCF_INIT_BYEXENAME = 0x00000002, ASSOCF_OPEN_BYEXENAME = 0x00000002, ASSOCF_INIT_DEFAULTTOSTAR = 0x00000004, ASSOCF_INIT_DEFAULTTOFOLDER = 0x00000008, ASSOCF_NOUSERSETTINGS = 0x00000010, ASSOCF_NOTRUNCATE = 0x00000020, ASSOCF_VERIFY = 0x00000040, ASSOCF_REMAPRUNDLL = 0x00000080, ASSOCF_NOFIXUPS = 0x00000100, ASSOCF_IGNOREBASECLASS = 0x00000200, ASSOCF_INIT_IGNOREUNKNOWN = 0x00000400, ASSOCF_INIT_FIXED_PROGID = 0x00000800, ASSOCF_IS_PROTOCOL = 0x00001000, ASSOCF_INIT_FOR_FILE = 0x00002000 } private enum AssocStr { ASSOCSTR_COMMAND = 1, ASSOCSTR_EXECUTABLE, ASSOCSTR_FRIENDLYDOCNAME, ASSOCSTR_FRIENDLYAPPNAME, ASSOCSTR_NOOPEN, ASSOCSTR_SHELLNEWVALUE, ASSOCSTR_DDECOMMAND, ASSOCSTR_DDEIFEXEC, ASSOCSTR_DDEAPPLICATION, ASSOCSTR_DDETOPIC, ASSOCSTR_INFOTIP, ASSOCSTR_QUICKTIP, ASSOCSTR_TILEINFO, ASSOCSTR_CONTENTTYPE, ASSOCSTR_DEFAULTICON, ASSOCSTR_SHELLEXTENSION, ASSOCSTR_DROPTARGET, ASSOCSTR_DELEGATEEXECUTE, ASSOCSTR_SUPPORTED_URI_PROTOCOLS, ASSOCSTR_PROGID, ASSOCSTR_APPID, ASSOCSTR_APPPUBLISHER, ASSOCSTR_APPICONREFERENCE, ASSOCSTR_MAX } }