Note that there are some explanatory texts on larger screens.

plurals
  1. PORun the command for a ProgId verb
    primarykey
    data
    text
    <p>Is there a way to execute the command for a progid verb without having to go digging in the registry and doing string manipulation?</p> <p>Using ShObjIdl.idl I can run the following command to get the ProgId for the default browser:</p> <pre><code>var reg = new ShellObjects.ApplicationAssociationRegistration(); string progID; reg.QueryCurrentDefault("http", ShellObjects.ASSOCIATIONTYPE.AT_URLPROTOCOL, ShellObjects.ASSOCIATIONLEVEL.AL_EFFECTIVE, out progID); </code></pre> <p>This gives me "ChromeHTML.FHXQEQDDJYXVQSFWM2SVMV5GNA". In the registry I can see this progid has the following shell/open/command:</p> <pre><code>"C:\Users\Paul\AppData\Local\Google\Chrome\Application\chrome.exe" -- "%1" </code></pre> <p>Is there an API that I can pass the ProgId to, along with the verb and argument and it will run it?</p> <p>One route I went down is using ShellExecuteEx:</p> <pre><code>var shellExecuteInfo = new SHELLEXECUTEINFO(); shellExecuteInfo.cbSize = Marshal.SizeOf(shellExecuteInfo); shellExecuteInfo.fMask = SEE_MASK_CLASSNAME; shellExecuteInfo.hwnd = IntPtr.Zero; shellExecuteInfo.lpVerb = "open"; shellExecuteInfo.lpFile = "google.com"; shellExecuteInfo.nShow = SW_SHOWNORMAL; shellExecuteInfo.lpClass = "http"; ShellExecuteEx(ref shellExecuteInfo); </code></pre> <p>However this fails with a 'Windows cannot find' error due to Window's doing checking on lpFile which I don't want to happen as it isn't relevant for a URL (from: <a href="http://blogs.msdn.com/b/oldnewthing/archive/2010/07/01/10033224.aspx" rel="nofollow">http://blogs.msdn.com/b/oldnewthing/archive/2010/07/01/10033224.aspx</a> )</p> <hr> <p>This is the solution I have come up with:</p> <pre><code> private static void Main(string[] args) { if (!OpenUrlInDefaultBrowser("google.com")) Console.WriteLine("An error happened"); } [DllImport("Shlwapi.dll")] private static extern int AssocQueryString(ASSOCF flags, ASSOCSTR str, string pszAssoc, string pszExtra, StringBuilder pszOut, ref uint pcchOut); private enum ASSOCF { ASSOCF_NONE = 0x00000000 } private enum ASSOCSTR { ASSOCSTR_COMMAND = 1 } [DllImport("Shell32.dll", CharSet=CharSet.Auto)] private static extern int SHEvaluateSystemCommandTemplate(string pszCmdTemplate, out string ppszApplication, out string ppszCommandLine, out string ppszParameters); private static bool OpenUrlInDefaultBrowser(string url) { string browserProgId; if (!GetDefaultBrowserProgId(out browserProgId)) return false; string browserCommandTemplate; if (!GetCommandTemplate(browserProgId, out browserCommandTemplate)) return false; string browserExecutable; string parameters; if (!EvaluateCommandTemplate(browserCommandTemplate, out browserExecutable, out parameters)) return false; parameters = ReplaceSubstitutionParameters(parameters, url); try { Process.Start(browserExecutable, parameters); } catch (InvalidOperationException) { return false; } catch (Win32Exception) { return false; } catch (FileNotFoundException) { return false; } return true; } private static bool GetDefaultBrowserProgId(out string defaultBrowserProgId) { try { // midl "C:\Program Files (x86)\Windows Kits\8.0\Include\um\ShObjIdl.idl" // tlbimp ShObjIdl.tlb var applicationAssociationRegistration = new ApplicationAssociationRegistration(); applicationAssociationRegistration.QueryCurrentDefault("http", ShellObjects.ASSOCIATIONTYPE.AT_URLPROTOCOL, ShellObjects.ASSOCIATIONLEVEL.AL_EFFECTIVE, out defaultBrowserProgId); } catch (COMException) { defaultBrowserProgId = null; return false; } return !string.IsNullOrEmpty(defaultBrowserProgId); } private static bool GetCommandTemplate(string defaultBrowserProgId, out string commandTemplate) { var commandTemplateBufferSize = 0U; AssocQueryString(ASSOCF.ASSOCF_NONE, ASSOCSTR.ASSOCSTR_COMMAND, defaultBrowserProgId, "open", null, ref commandTemplateBufferSize); var commandTemplateStringBuilder = new StringBuilder((int)commandTemplateBufferSize); var hresult = AssocQueryString(ASSOCF.ASSOCF_NONE, ASSOCSTR.ASSOCSTR_COMMAND, defaultBrowserProgId, "open", commandTemplateStringBuilder, ref commandTemplateBufferSize); commandTemplate = commandTemplateStringBuilder.ToString(); return hresult == 0 &amp;&amp; !string.IsNullOrEmpty(commandTemplate); } private static bool EvaluateCommandTemplate(string commandTemplate, out string application, out string parameters) { string commandLine; var hresult = SHEvaluateSystemCommandTemplate(commandTemplate, out application, out commandLine, out parameters); return hresult == 0 &amp;&amp; !string.IsNullOrEmpty(application) &amp;&amp; !string.IsNullOrEmpty(parameters); } private static string ReplaceSubstitutionParameters(string parameters, string replacement) { // Not perfect but good enough for this purpose return parameters.Replace("%L", replacement) .Replace("%l", replacement) .Replace("%1", replacement); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload