Files
PowerToys/src/modules/launcher/Wox.Plugin/Common/DefaultBrowserInfo.cs

207 lines
8.9 KiB
C#
Raw Normal View History

// Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
using System.Text;
[Dev][Build] .NET 9 Upgrade (#35716) * [Deps] Upgrade Framework Libraries to .NET 9 RC2 * [Common][Build] Update TFM to NET9 * [FileLocksmith][Build] Update TFM to NET9 in Publish Profile * [PreviewPane][Build] Update TFM to NET9 in Publish Profile * [PTRun][Build] Update TFM to NET9 in Publish Profile * [Settings][Build] Update TFM to NET9 in Publish Profile * [MouseWithoutBorders][Analyzers] Resolve WFO1000 by configuring Designer Serialization Visibility * [Deps] Update Microsoft.CodeAnalysis.NetAnalyzers * [Analyzers] Set CA1859,CA2263,CA2022 to be excluded from error * [MouseWithoutBorders] Use System.Threading.Lock to lock instead of object instance * [ColorPicker] Use System.Threading.Lock to lock instead of object instance * [AdvancedPaste] Use System.Threading.Lock to lock instead of object instance * [TextExtractor] Use System.Threading.Lock to lock instead of object instance * [Hosts] Use System.Threading.Lock to lock instead of object instance * [MouseJump] Use System.Threading.Lock to lock instead of object instance * [PTRun] Use System.Threading.Lock to lock instead of object instance * [Wox] Use System.Threading.Lock to lock instead of object instance * [Peek] Use System.Threading.Lock to lock instead of object instance * [PowerAccent] Use System.Threading.Lock to lock instead of object instance * [Settings] Use System.Threading.Lock to lock instead of object instance * [Deps] Update NOTICE.md * [CI] Update .NET version step to target 9.0 * [Build] Attempt to add manual trigger for using Visual Studio Preview for building * [Build] Fix variable typo * [Build][Temporary] set to use preview builds * [Build] Add missing parameters * [Build][Temporary] directly hardcode preview image * [Build][Temporary] Trying ImageOverride * [Build] Revert hardcode and use ImageOverride * [Build] Add env var for adding prerelease argument for vswhere * [Build] Update VCToolsVersion script to use env var to optionally add prerelease version checking * [Build] Remove unneeded parameter * [Build] Re-add parameter in all the right places * [CI][Build] Add NoWarn NU5104 when building with VS Preview * [Deps] Update to stable .NET 9 packages * [Deps] Update NOTICE.md * Everything is WPF and WindowsForms now to fix .NET 9 dependency conflicts * Ensure .NET 9 SDK for tests too --------- Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
2024-11-13 12:36:45 -05:00
using System.Threading;
using Wox.Plugin.Common.Win32;
using Wox.Plugin.Logger;
namespace Wox.Plugin.Common
{
/// <summary>
/// Contains information (e.g. path to executable, name...) about the default browser.
/// </summary>
public static class DefaultBrowserInfo
{
[Dev][Build] .NET 9 Upgrade (#35716) * [Deps] Upgrade Framework Libraries to .NET 9 RC2 * [Common][Build] Update TFM to NET9 * [FileLocksmith][Build] Update TFM to NET9 in Publish Profile * [PreviewPane][Build] Update TFM to NET9 in Publish Profile * [PTRun][Build] Update TFM to NET9 in Publish Profile * [Settings][Build] Update TFM to NET9 in Publish Profile * [MouseWithoutBorders][Analyzers] Resolve WFO1000 by configuring Designer Serialization Visibility * [Deps] Update Microsoft.CodeAnalysis.NetAnalyzers * [Analyzers] Set CA1859,CA2263,CA2022 to be excluded from error * [MouseWithoutBorders] Use System.Threading.Lock to lock instead of object instance * [ColorPicker] Use System.Threading.Lock to lock instead of object instance * [AdvancedPaste] Use System.Threading.Lock to lock instead of object instance * [TextExtractor] Use System.Threading.Lock to lock instead of object instance * [Hosts] Use System.Threading.Lock to lock instead of object instance * [MouseJump] Use System.Threading.Lock to lock instead of object instance * [PTRun] Use System.Threading.Lock to lock instead of object instance * [Wox] Use System.Threading.Lock to lock instead of object instance * [Peek] Use System.Threading.Lock to lock instead of object instance * [PowerAccent] Use System.Threading.Lock to lock instead of object instance * [Settings] Use System.Threading.Lock to lock instead of object instance * [Deps] Update NOTICE.md * [CI] Update .NET version step to target 9.0 * [Build] Attempt to add manual trigger for using Visual Studio Preview for building * [Build] Fix variable typo * [Build][Temporary] set to use preview builds * [Build] Add missing parameters * [Build][Temporary] directly hardcode preview image * [Build][Temporary] Trying ImageOverride * [Build] Revert hardcode and use ImageOverride * [Build] Add env var for adding prerelease argument for vswhere * [Build] Update VCToolsVersion script to use env var to optionally add prerelease version checking * [Build] Remove unneeded parameter * [Build] Re-add parameter in all the right places * [CI][Build] Add NoWarn NU5104 when building with VS Preview * [Deps] Update to stable .NET 9 packages * [Deps] Update NOTICE.md * Everything is WPF and WindowsForms now to fix .NET 9 dependency conflicts * Ensure .NET 9 SDK for tests too --------- Co-authored-by: Jaime Bernardo <jaime@janeasystems.com>
2024-11-13 12:36:45 -05:00
private static readonly Lock _updateLock = new Lock();
/// <summary>Gets the path to the MS Edge browser executable.</summary>
[Run] Improve default browser detection (#34132) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request - Some users are reporting that the WebSearch plugin is opening Explorer instead of the browser. - A user reported that the registry value we are using to detect the command pattern to start the browser contains the string `Microsoft Edge HTML Document`: https://github.com/microsoft/PowerToys/issues/21400#issuecomment-2262764771 - Can't find the reason why that string is here but rather than dealing with this string, if the pattern isn't "something valid" to be launched, use Edge. The code is already falling back to Edge in other error cases. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] **Closes:** #21400 - [ ] **Communication:** I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end user facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments - Small QoL improvements to the code - Logged the command in case of error - Fall back to Edge if command isn't a valid path or URI <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed - Tested WebSearch plugin changing the value of `HKEY_CLASSES_ROOT\MSEdgeHTM\shell\open\command`: - `"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument %1` - `shell:AppsFolder\Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe!App %1` - `Microsoft Edge HTML Document`
2024-08-07 09:38:40 +02:00
public static string MSEdgePath => System.IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ProgramFilesX86),
@"Microsoft\Edge\Application\msedge.exe");
/// <summary>Gets the command line pattern of the MS Edge.</summary>
[Run] Improve default browser detection (#34132) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request - Some users are reporting that the WebSearch plugin is opening Explorer instead of the browser. - A user reported that the registry value we are using to detect the command pattern to start the browser contains the string `Microsoft Edge HTML Document`: https://github.com/microsoft/PowerToys/issues/21400#issuecomment-2262764771 - Can't find the reason why that string is here but rather than dealing with this string, if the pattern isn't "something valid" to be launched, use Edge. The code is already falling back to Edge in other error cases. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] **Closes:** #21400 - [ ] **Communication:** I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end user facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments - Small QoL improvements to the code - Logged the command in case of error - Fall back to Edge if command isn't a valid path or URI <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed - Tested WebSearch plugin changing the value of `HKEY_CLASSES_ROOT\MSEdgeHTM\shell\open\command`: - `"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument %1` - `shell:AppsFolder\Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe!App %1` - `Microsoft Edge HTML Document`
2024-08-07 09:38:40 +02:00
public const string MSEdgeArgumentsPattern = "--single-argument %1";
public const string MSEdgeName = "Microsoft Edge";
/// <summary>Gets the path to default browser's executable.</summary>
public static string Path { get; private set; }
/// <summary>Gets <see cref="Path"/> since the icon is embedded in the executable.</summary>
public static string IconPath => Path;
/// <summary>Gets the user-friendly name of the default browser.</summary>
public static string Name { get; private set; }
/// <summary>Gets the command line pattern of the default browser.</summary>
public static string ArgumentsPattern { get; private set; }
public static bool IsDefaultBrowserSet { get => !string.IsNullOrEmpty(Path); }
public const long UpdateTimeout = 300;
private static long _lastUpdateTickCount = -UpdateTimeout;
[Run] Improve default browser detection (#34132) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request - Some users are reporting that the WebSearch plugin is opening Explorer instead of the browser. - A user reported that the registry value we are using to detect the command pattern to start the browser contains the string `Microsoft Edge HTML Document`: https://github.com/microsoft/PowerToys/issues/21400#issuecomment-2262764771 - Can't find the reason why that string is here but rather than dealing with this string, if the pattern isn't "something valid" to be launched, use Edge. The code is already falling back to Edge in other error cases. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] **Closes:** #21400 - [ ] **Communication:** I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end user facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments - Small QoL improvements to the code - Logged the command in case of error - Fall back to Edge if command isn't a valid path or URI <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed - Tested WebSearch plugin changing the value of `HKEY_CLASSES_ROOT\MSEdgeHTM\shell\open\command`: - `"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument %1` - `shell:AppsFolder\Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe!App %1` - `Microsoft Edge HTML Document`
2024-08-07 09:38:40 +02:00
private static bool _updatedOnce;
private static bool _errorLogged;
/// <summary>
/// Updates only if at least more than 300ms has passed since the last update, to avoid multiple calls to <see cref="Update"/>.
/// (because of multiple plugins calling update at the same time.)
/// </summary>
public static void UpdateIfTimePassed()
{
long curTickCount = Environment.TickCount64;
if (curTickCount - _lastUpdateTickCount >= UpdateTimeout)
{
_lastUpdateTickCount = curTickCount;
Update();
}
}
/// <summary>
/// Consider using <see cref="UpdateIfTimePassed"/> to avoid updating multiple times.
/// (because of multiple plugins calling update at the same time.)
/// </summary>
public static void Update()
{
lock (_updateLock)
{
[Run] Improve default browser detection (#34132) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request - Some users are reporting that the WebSearch plugin is opening Explorer instead of the browser. - A user reported that the registry value we are using to detect the command pattern to start the browser contains the string `Microsoft Edge HTML Document`: https://github.com/microsoft/PowerToys/issues/21400#issuecomment-2262764771 - Can't find the reason why that string is here but rather than dealing with this string, if the pattern isn't "something valid" to be launched, use Edge. The code is already falling back to Edge in other error cases. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] **Closes:** #21400 - [ ] **Communication:** I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end user facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments - Small QoL improvements to the code - Logged the command in case of error - Fall back to Edge if command isn't a valid path or URI <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed - Tested WebSearch plugin changing the value of `HKEY_CLASSES_ROOT\MSEdgeHTM\shell\open\command`: - `"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument %1` - `shell:AppsFolder\Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe!App %1` - `Microsoft Edge HTML Document`
2024-08-07 09:38:40 +02:00
if (!_updatedOnce)
{
[Run] Improve default browser detection (#34132) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request - Some users are reporting that the WebSearch plugin is opening Explorer instead of the browser. - A user reported that the registry value we are using to detect the command pattern to start the browser contains the string `Microsoft Edge HTML Document`: https://github.com/microsoft/PowerToys/issues/21400#issuecomment-2262764771 - Can't find the reason why that string is here but rather than dealing with this string, if the pattern isn't "something valid" to be launched, use Edge. The code is already falling back to Edge in other error cases. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] **Closes:** #21400 - [ ] **Communication:** I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end user facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments - Small QoL improvements to the code - Logged the command in case of error - Fall back to Edge if command isn't a valid path or URI <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed - Tested WebSearch plugin changing the value of `HKEY_CLASSES_ROOT\MSEdgeHTM\shell\open\command`: - `"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument %1` - `shell:AppsFolder\Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe!App %1` - `Microsoft Edge HTML Document`
2024-08-07 09:38:40 +02:00
Log.Info("I've tried updating the chosen Web Browser info at least once.", typeof(DefaultBrowserInfo));
_updatedOnce = true;
}
try
{
string progId = GetRegistryValue(
Fix default browser detection for Windows 11 24H2 by checking UserChoiceLatest\ProgId registry key (#40115) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request This actually fixes an issue with #39794. What I failed to mention in the original issue was the additional path under the registry that the new key is located under. Instead of the key being stored directly in `UserChoiceLatest` in a key named `ProgId`, the path also includes a second `ProgId` as well. Copilot tried to fix this issue in #40035, but because I had failed to mention the additional `ProgId` in the path, it was not included in Copilot's fix. Therefore, the true new path is `.../UserChoiceLatest/ProgId` <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] **Closes:** #39794 - [ ] **Communication:** I've discussed this with core contributors already. If the work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end-user-facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed, or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments ![image](https://github.com/user-attachments/assets/25aeb494-c323-4db4-8897-cdc52bcade52) <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed
2025-06-18 18:24:57 -06:00
@"HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoiceLatest\ProgId",
Fix default browser detection for Windows 11 24H2 by checking UserChoiceLatest registry key (#40035) ## Summary This PR fixes an issue where PowerToys Web Search and PowerToys Run would always open Microsoft Edge instead of the user's default browser on Windows 11 24H2, even when a different browser like Firefox was set as the default. ## Root Cause Windows 11 24H2 introduced a change where default browser associations are now stored in a new registry location: - **New location**: `HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoiceLatest` - **Old location**: `HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice` PowerToys was only checking the old registry location, causing it to fail to find the default browser and fall back to Microsoft Edge. ## Changes Made Updated both `DefaultBrowserInfo.cs` files to check the new registry location first, then fall back to the old location for backward compatibility: 1. **Command Palette Web Search**: `src/modules/cmdpal/ext/Microsoft.CmdPal.Ext.WebSearch/Helpers/DefaultBrowserInfo.cs` 2. **PowerToys Run**: `src/modules/launcher/Wox.Plugin/Common/DefaultBrowserInfo.cs` **Before**: ```csharp var progId = GetRegistryValue( @"HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice", "ProgId"); ``` **After**: ```csharp var progId = GetRegistryValue( @"HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoiceLatest", "ProgId") ?? GetRegistryValue( @"HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice", "ProgId"); ``` ## Testing - Verified the fallback logic works correctly with a test application - Confirmed both affected files are updated with the same pattern - Ensured backward compatibility with older Windows versions ## Impact This fix ensures that: - Users on Windows 11 24H2 will have their default browser respected - Older Windows versions continue to work as before - No breaking changes are introduced Fixes #39794. <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs. --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: crutkas <1462282+crutkas@users.noreply.github.com>
2025-06-18 09:16:23 -07:00
"ProgId")
?? GetRegistryValue(
@"HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice",
"ProgId");
string appName = GetRegistryValue($@"HKEY_CLASSES_ROOT\{progId}\Application", "ApplicationName")
?? GetRegistryValue($@"HKEY_CLASSES_ROOT\{progId}", "FriendlyTypeName");
if (appName != null)
{
// Handle indirect strings:
if (appName.StartsWith('@'))
{
appName = GetIndirectString(appName);
}
appName = appName
.Replace("URL", null, StringComparison.OrdinalIgnoreCase)
.Replace("HTML", null, StringComparison.OrdinalIgnoreCase)
.Replace("Document", null, StringComparison.OrdinalIgnoreCase)
.Replace("Web", null, StringComparison.OrdinalIgnoreCase)
.TrimEnd();
}
Name = appName;
string commandPattern = GetRegistryValue($@"HKEY_CLASSES_ROOT\{progId}\shell\open\command", null);
if (string.IsNullOrEmpty(commandPattern))
{
throw new ArgumentOutOfRangeException(
nameof(commandPattern),
"Default browser program command is not specified.");
}
if (commandPattern.StartsWith('@'))
{
commandPattern = GetIndirectString(commandPattern);
}
// HACK: for firefox installed through Microsoft store
// When installed through Microsoft Firefox the commandPattern does not have
// quotes for the path. As the Program Files does have a space
// the extracted path would be invalid, here we add the quotes to fix it
const string FirefoxExecutableName = "firefox.exe";
if (commandPattern.Contains(FirefoxExecutableName) && commandPattern.Contains(@"\WindowsApps\") && (!commandPattern.StartsWith('\"')))
{
var pathEndIndex = commandPattern.IndexOf(FirefoxExecutableName, StringComparison.Ordinal) + FirefoxExecutableName.Length;
commandPattern = commandPattern.Insert(pathEndIndex, "\"");
commandPattern = commandPattern.Insert(0, "\"");
}
if (commandPattern.StartsWith('\"'))
{
var endQuoteIndex = commandPattern.IndexOf('\"', 1);
if (endQuoteIndex != -1)
{
Path = commandPattern.Substring(1, endQuoteIndex - 1);
ArgumentsPattern = commandPattern.Substring(endQuoteIndex + 1).Trim();
}
}
else
{
var spaceIndex = commandPattern.IndexOf(' ');
if (spaceIndex != -1)
{
Path = commandPattern.Substring(0, spaceIndex);
ArgumentsPattern = commandPattern.Substring(spaceIndex + 1).Trim();
}
}
[Run] Improve default browser detection (#34132) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request - Some users are reporting that the WebSearch plugin is opening Explorer instead of the browser. - A user reported that the registry value we are using to detect the command pattern to start the browser contains the string `Microsoft Edge HTML Document`: https://github.com/microsoft/PowerToys/issues/21400#issuecomment-2262764771 - Can't find the reason why that string is here but rather than dealing with this string, if the pattern isn't "something valid" to be launched, use Edge. The code is already falling back to Edge in other error cases. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] **Closes:** #21400 - [ ] **Communication:** I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end user facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments - Small QoL improvements to the code - Logged the command in case of error - Fall back to Edge if command isn't a valid path or URI <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed - Tested WebSearch plugin changing the value of `HKEY_CLASSES_ROOT\MSEdgeHTM\shell\open\command`: - `"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument %1` - `shell:AppsFolder\Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe!App %1` - `Microsoft Edge HTML Document`
2024-08-07 09:38:40 +02:00
// Packaged applications could be an URI. Example: shell:AppsFolder\Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe!App
if (!System.IO.Path.Exists(Path) && !Uri.TryCreate(Path, UriKind.Absolute, out _))
{
throw new ArgumentException(
$"Command validation failed: {commandPattern}",
nameof(commandPattern));
}
if (string.IsNullOrEmpty(Path))
{
throw new ArgumentOutOfRangeException(
nameof(Path),
"Default browser program path could not be determined.");
}
}
catch (Exception e)
{
[Run] Improve default browser detection (#34132) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request - Some users are reporting that the WebSearch plugin is opening Explorer instead of the browser. - A user reported that the registry value we are using to detect the command pattern to start the browser contains the string `Microsoft Edge HTML Document`: https://github.com/microsoft/PowerToys/issues/21400#issuecomment-2262764771 - Can't find the reason why that string is here but rather than dealing with this string, if the pattern isn't "something valid" to be launched, use Edge. The code is already falling back to Edge in other error cases. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] **Closes:** #21400 - [ ] **Communication:** I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end user facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments - Small QoL improvements to the code - Logged the command in case of error - Fall back to Edge if command isn't a valid path or URI <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed - Tested WebSearch plugin changing the value of `HKEY_CLASSES_ROOT\MSEdgeHTM\shell\open\command`: - `"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument %1` - `shell:AppsFolder\Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe!App %1` - `Microsoft Edge HTML Document`
2024-08-07 09:38:40 +02:00
// Fallback to MS Edge
Path = MSEdgePath;
Name = MSEdgeName;
ArgumentsPattern = MSEdgeArgumentsPattern;
[Run] Improve default browser detection (#34132) <!-- Enter a brief description/summary of your PR here. What does it fix/what does it change/how was it tested (even manually, if necessary)? --> ## Summary of the Pull Request - Some users are reporting that the WebSearch plugin is opening Explorer instead of the browser. - A user reported that the registry value we are using to detect the command pattern to start the browser contains the string `Microsoft Edge HTML Document`: https://github.com/microsoft/PowerToys/issues/21400#issuecomment-2262764771 - Can't find the reason why that string is here but rather than dealing with this string, if the pattern isn't "something valid" to be launched, use Edge. The code is already falling back to Edge in other error cases. <!-- Please review the items on the PR checklist before submitting--> ## PR Checklist - [x] **Closes:** #21400 - [ ] **Communication:** I've discussed this with core contributors already. If work hasn't been agreed, this work might be rejected - [ ] **Tests:** Added/updated and all pass - [ ] **Localization:** All end user facing strings can be localized - [ ] **Dev docs:** Added/updated - [ ] **New binaries:** Added on the required places - [ ] [JSON for signing](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ESRPSigning_core.json) for new binaries - [ ] [WXS for installer](https://github.com/microsoft/PowerToys/blob/main/installer/PowerToysSetup/Product.wxs) for new binaries and localization folder - [ ] [YML for CI pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/ci/templates/build-powertoys-steps.yml) for new test projects - [ ] [YML for signed pipeline](https://github.com/microsoft/PowerToys/blob/main/.pipelines/release.yml) - [ ] **Documentation updated:** If checked, please file a pull request on [our docs repo](https://github.com/MicrosoftDocs/windows-uwp/tree/docs/hub/powertoys) and link it here: #xxx <!-- Provide a more detailed description of the PR, other things fixed or any additional comments/features here --> ## Detailed Description of the Pull Request / Additional comments - Small QoL improvements to the code - Logged the command in case of error - Fall back to Edge if command isn't a valid path or URI <!-- Describe how you validated the behavior. Add automated tests wherever possible, but list manual validation steps taken as well --> ## Validation Steps Performed - Tested WebSearch plugin changing the value of `HKEY_CLASSES_ROOT\MSEdgeHTM\shell\open\command`: - `"C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe" --single-argument %1` - `shell:AppsFolder\Microsoft.MicrosoftEdge.Stable_8wekyb3d8bbwe!App %1` - `Microsoft Edge HTML Document`
2024-08-07 09:38:40 +02:00
if (!_errorLogged)
{
Log.Exception("Exception when retrieving browser path/name. Path and Name are set to use Microsoft Edge.", e, typeof(DefaultBrowserInfo));
_errorLogged = true;
}
}
string GetRegistryValue(string registryLocation, string valueName)
{
return Microsoft.Win32.Registry.GetValue(registryLocation, valueName, null) as string;
}
string GetIndirectString(string str)
{
var stringBuilder = new StringBuilder(128);
if (NativeMethods.SHLoadIndirectString(
str,
stringBuilder,
(uint)stringBuilder.Capacity,
IntPtr.Zero)
== HRESULT.S_OK)
{
return stringBuilder.ToString();
}
throw new ArgumentNullException(nameof(str), "Could not load indirect string.");
}
}
}
}
}