{"record":{"id":"e98d31502e48c764","repo":"dotnet/wpf","slug":"sr-failtolaunchdefaultbrowser","errorCode":null,"errorMessage":"SR.FailToLaunchDefaultBrowser","messagePattern":"SR\\.FailToLaunchDefaultBrowser","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/AppModel/AppSecurityManager.cs","lineNumber":136,"sourceCode":"            UnsafeNativeMethods.ShellExecuteInfo sei = new UnsafeNativeMethods.ShellExecuteInfo();\n            sei.cbSize = Marshal.SizeOf(sei);\n            sei.fMask = UnsafeNativeMethods.ShellExecuteFlags.SEE_MASK_FLAG_DDEWAIT;\n            /*\n            There is a bug on Windows Vista (with IE 7): ShellExecute via SEE_MASK_CLASSNAME fails for an \n            http[s]:// URL. It works fine for file://. The cause appears to be that the DDE command template\n            defined in HKCR\\IE.AssocFile.HTM\\shell\\opennew\\ddeexec is used: [file://%1\",-1,,,,,]. On XP, the\n            the key used is (supposedly) HKCR\\htmlfile\\shell\\opennew\\ddeexec, and its value is [\"%1\",,-1,0,,,,].\n            The workaround here is to add the SEE_MASK_CLASSNAME flag only for non-HTTP URLs. For HTTP, \n            \"plain\" ShellExecute just works, incl. with Firefox/Netscape as the default browser.\n            */\n            if (uri.Scheme != Uri.UriSchemeHttp && uri.Scheme != Uri.UriSchemeHttps)\n            {\n                sei.fMask |= UnsafeNativeMethods.ShellExecuteFlags.SEE_MASK_CLASSNAME;\n                sei.lpClass = \".htm\"; // The default browser is looked up by this.\n            }\n            sei.lpFile = uri.ToString(); // It's safe to use Uri.ToString since there's an inheritance demand on it that prevents spoofing by subclasses.\n            if (!UnsafeNativeMethods.ShellExecuteEx(sei))\n                throw new InvalidOperationException(SR.FailToLaunchDefaultBrowser,\n                    new System.ComponentModel.Win32Exception(/*uses the last Win32 error*/));\n        }\n    }\n}\n","sourceCodeStart":118,"sourceCodeEnd":141,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationFramework/MS/Internal/AppModel/AppSecurityManager.cs#L118-L141","documentation":"AppSecurityManager.ShellExecuteDefaultBrowser calls ShellExecuteEx to open the URI in the system default browser; when the native call returns false it throws InvalidOperationException wrapping a Win32Exception built from the last Win32 error. It means Windows refused to launch the default browser process, so the (unsafe) navigation could not be performed.","triggerScenarios":"UnsafeLaunchBrowser path invoking ShellExecuteDefaultBrowser with a URI while ShellExecuteEx fails — e.g. no default browser is registered, the .htm class lookup fails, or the shell refuses execution (corrupt/missing association, policy restrictions).","commonSituations":"Machines with no default browser set or a broken http/.htm file association; locked-down corporate desktops blocking ShellExecute; securable navigation to external URLs from a WPF app.","solutions":["Inspect the inner Win32Exception's NativeErrorCode to identify the shell failure; fix the default browser registration (Settings > Default apps) or re-register the .htm/http association.","Verify a default browser is installed and set; call ShellExecute directly on a known browser if none exists.","Handle the exception in UnsafeLaunchBrowser and surface a friendly message or fall back to a manually chosen browser path (e.g. Process.Start with an explicit exe)."],"exampleFix":"// before\nUnsafeLaunchBrowser(new Uri(\"https://example.com\"));\n// after\ntry\n{\n    UnsafeLaunchBrowser(new Uri(\"https://example.com\"));\n}\ncatch (InvalidOperationException ex)\n{\n    var win32 = ex.InnerException as Win32Exception;\n    logger.Warn($\"Browser launch failed: {win32?.NativeErrorCode}\");\n    Process.Start(new ProcessStartInfo(\"explorer.exe\", uri.ToString()));\n}","handlingStrategy":"try-catch","validationCode":"using var key = Microsoft.Win32.Registry.ClassesRoot.OpenSubKey(@\"http\\shell\\open\\command\");\nbool defaultBrowserRegistered = key != null;","typeGuard":null,"tryCatchPattern":"try { UnsafeLaunchBrowser(uri); }\ncatch (InvalidOperationException ex)\n    when (ex.InnerException is System.ComponentModel.Win32Exception win32)\n{\n    // handle win32.NativeErrorCode, prompt user or fall back\n}","preventionTips":["Verify a default browser/ http association exists before shell-executing external URIs.","Log the inner Win32Exception native error code for diagnosis.","Provide a fallback launch path (explicit browser executable) for locked-down machines."],"tags":["wpf","shell-execute","browser","win32","security"],"backgroundTag":"http-request-failed","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}