Windows 10ではレジストリに記録される拡張子の関連付け情報が複雑で、レジストリを直接操作すると互換性が失われる可能性があります。shlwapi.dllの公開するAssocQueryStringW
関数の使用でこの複雑さや互換性を解決できます。
なお、AssocQueryStringA
でAnsi版、IQueryAssociations
の利用でより詳細な情報を取得できます。
using System; using System.Runtime.InteropServices; using System.Text; using Potisan.Windows.Shell; class Program { static void Main() { foreach (var name in Enum.GetNames<QueryAssocString.AssocStr>()) { var value = QueryAssocString.Query( QueryAssocString.AssocFlags.None, Enum.Parse<QueryAssocString.AssocStr>(name), @".ps1"); Console.WriteLine($"{name}: {value}"); } Console.WriteLine(); /* Command: Executable: "C:\Program Files\PowerShell\7\pwsh.exe" -NoExit "%1" FriendlyDocName: C:\Program Files\PowerShell\7\pwsh.exe FriendlyAppName: PS1 ファイル NoOpen: pwsh ShellNewValue: DDECommand: DDEIfExec: DDEApplication: DDETopic: pwsh InfoTip: System QuickTip: prop:System.ItemTypeText;System.Size;System.DateModified TileInfo: prop:System.ItemTypeText;System.Size;System.DateModified ContentType: prop:System.ItemTypeText;System.Size;System.DateModified DefaultIcon: ShellExtension: C:\Program Files\PowerShell\7\pwsh.exe DropTarget: DelegateExecute: SupportedURIProtocols: ProgID: file: AppID: Applications\pwsh.exe AppPublisher: AppIconReference: Microsoft Corporation Max: C:\Program Files\PowerShell\7\pwsh.exe */ foreach (var name in Enum.GetNames<QueryAssocString.AssocStr>()) { var value = QueryAssocString.Query( QueryAssocString.AssocFlags.None, Enum.Parse<QueryAssocString.AssocStr>(name), @".exe"); Console.WriteLine($"{name}: {value}"); } /* Command: Executable: "%1" %* FriendlyDocName: %1 FriendlyAppName: アプリケーション NoOpen: ShellNewValue: DDECommand: DDEIfExec: DDEApplication: DDETopic: %1 InfoTip: System QuickTip: prop:System.FileDescription;System.Company;System.FileVersion;System.DateCreated;System.Size TileInfo: prop:System.ItemTypeText;System.Size;System.DateModified ContentType: prop:System.FileDescription;System.Company;System.FileVersion;System.DateCreated;System.Size DefaultIcon: ShellExtension: %1 DropTarget: DelegateExecute: SupportedURIProtocols: ProgID: file: AppID: exefile AppPublisher: AppIconReference: Max: %1 */ } } namespace Potisan.Windows.Shell { public static class QueryAssocString { public static string Query( AssocFlags flags, AssocStr str, string assoc, string extra = null, bool throwsException = false) { const int ASSOCF_NOTRUNCATE = 0x00000020; var hr = NativeMethods.AssocQueryStringW( (int)flags, (int)str, assoc, extra, null, out var bufferSize); if (hr < 0) { if (throwsException) Marshal.ThrowExceptionForHR(hr); else return null; } var buffer = new StringBuilder((int)bufferSize); NativeMethods.AssocQueryStringW( (int)flags | ASSOCF_NOTRUNCATE, (int)str, assoc, extra, buffer, out bufferSize); if (hr < 0) { if (throwsException) Marshal.ThrowExceptionForHR(hr); else return null; } return buffer.ToString(); } private static class NativeMethods { [DllImport("shlwapi.dll", CharSet = CharSet.Unicode)] public static extern int AssocQueryStringW( int flags, int str, [In] string pszAssoc, [In] string pszExtra, StringBuilder pszOut, out uint pcchOut); } private const int MAX_PATH = 260; public enum AssocFlags : int { /// <summary>ASSOCF_NONE</summary> None = 0x00000000, /// <summary>ASSOCF_INIT_NOREMAPCLSID</summary> InitNoRemapCLSID = 0x00000001, /// <summary>ASSOCF_INIT_BYEXENAME</summary> InitByExeName = 0x00000002, /// <summary>ASSOCF_OPEN_BYEXENAME</summary> OpenByExeName = 0x00000002, /// <summary>ASSOCF_INIT_DEFAULTTOSTAR</summary> InitDefaultToStar = 0x00000004, /// <summary>ASSOCF_INIT_DEFAULTTOFOLDER</summary> InitDefaultToFolder = 0x00000008, /// <summary>ASSOCF_NOUSERSETTINGS</summary> NoUserSettings = 0x00000010, // ASSOCF_NOTRUNCATE</summary> /// <summary>ASSOCF_VERIFY = 0x00000040, Verify = 0x00000040, /// <summary>ASSOCF_REMAPRUNDLL</summary> RemapRunDLL = 0x00000080, /// <summary>ASSOCF_NOFIXUPS</summary> NoFixups = 0x00000100, /// <summary>ASSOCF_IGNOREBASECLASS</summary> IgnoreBaseClass = 0x00000200, /// <summary>ASSOCF_INIT_IGNOREUNKNOWN</summary> InitIgnoreUnknown = 0x00000400, /// <summary>ASSOCF_INIT_FIXED_PROGID</summary> InitFixedProgID = 0x00000800, /// <summary>ASSOCF_IS_PROTOCOL</summary> IsProtocol = 0x00001000, /// <summary>ASSOCF_INIT_FOR_FILE</summary> InitForFile = 0x00002000 } public enum AssocStr : int { /// <summary>ASSOCSTR_COMMAND</summary> Command, /// <summary>ASSOCSTR_EXECUTABLE</summary> Executable, /// <summary>ASSOCSTR_FRIENDLYDOCNAME</summary> FriendlyDocName, /// <summary>ASSOCSTR_FRIENDLYAPPNAME</summary> FriendlyAppName, /// <summary>ASSOCSTR_NOOPEN</summary> NoOpen, /// <summary>ASSOCSTR_SHELLNEWVALUE</summary> ShellNewValue, /// <summary>ASSOCSTR_DDECOMMAND</summary> DDECommand, /// <summary>ASSOCSTR_DDEIFEXEC</summary> DDEIfExec, /// <summary>ASSOCSTR_DDEAPPLICATION</summary> DDEApplication, /// <summary>ASSOCSTR_DDETOPIC</summary> DDETopic, /// <summary>ASSOCSTR_INFOTIP</summary> InfoTip, /// <summary>ASSOCSTR_QUICKTIP</summary> QuickTip, /// <summary>ASSOCSTR_TILEINFO</summary> TileInfo, /// <summary>ASSOCSTR_CONTENTTYPE</summary> ContentType, /// <summary>ASSOCSTR_DEFAULTICON</summary> DefaultIcon, /// <summary>ASSOCSTR_SHELLEXTENSION</summary> ShellExtension, /// <summary>ASSOCSTR_DROPTARGET</summary> DropTarget, /// <summary>ASSOCSTR_DELEGATEEXECUTE</summary> DelegateExecute, /// <summary>ASSOCSTR_SUPPORTED_URI_PROTOCOLS</summary> SupportedURIProtocols, /// <summary>ASSOCSTR_PROGID</summary> ProgID, /// <summary>ASSOCSTR_APPID</summary> AppID, /// <summary>ASSOCSTR_APPPUBLISHER</summary> AppPublisher, /// <summary>ASSOCSTR_APPICONREFERENCE</summary> AppIconReference, /// <summary>ASSOCSTR_MAX</summary> Max } } }