[Run]New plugin to start other PowerToys (#24934)

* PowerToys plugin

* bring setting window to foreground

* resources

* fix deep linking always opening general page

* dll signing

* setup

* registry preview added

* align registry preview icon and setup

* fix setup

* fix setup build

* PR feedbacks addressed
This commit is contained in:
Davide Giacometti
2023-05-02 13:10:54 +02:00
committed by GitHub
parent 0aeab56a60
commit 471bb3bba2
33 changed files with 1096 additions and 41 deletions

View File

@@ -109,7 +109,8 @@
"modules\\launcher\\Plugins\\Folder\\Microsoft.Plugin.Folder.dll", "modules\\launcher\\Plugins\\Folder\\Microsoft.Plugin.Folder.dll",
"modules\\launcher\\Plugins\\Indexer\\Microsoft.Plugin.Indexer.dll", "modules\\launcher\\Plugins\\Indexer\\Microsoft.Plugin.Indexer.dll",
"modules\\launcher\\Plugins\\OneNote\\Microsoft.PowerToys.Run.Plugin.OneNote.dll", "modules\\launcher\\Plugins\\OneNote\\Microsoft.PowerToys.Run.Plugin.OneNote.dll",
"modules\\launcher\\Plugins\\History\\Microsoft.PowerToys.Run.Plugin.History.dll", "modules\\launcher\\Plugins\\History\\Microsoft.PowerToys.Run.Plugin.History.dll",
"modules\\launcher\\Plugins\\PowerToys\\Microsoft.PowerToys.Run.Plugin.PowerToys.dll",
"modules\\launcher\\Plugins\\Program\\Microsoft.Plugin.Program.dll", "modules\\launcher\\Plugins\\Program\\Microsoft.Plugin.Program.dll",
"modules\\launcher\\Plugins\\Registry\\Microsoft.PowerToys.Run.Plugin.Registry.dll", "modules\\launcher\\Plugins\\Registry\\Microsoft.PowerToys.Run.Plugin.Registry.dll",
"modules\\launcher\\Plugins\\WindowsSettings\\Microsoft.PowerToys.Run.Plugin.WindowsSettings.dll", "modules\\launcher\\Plugins\\WindowsSettings\\Microsoft.PowerToys.Run.Plugin.WindowsSettings.dll",

View File

@@ -129,6 +129,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PowerLauncher", "src\module
{0351ADA4-0C32-4652-9BA0-41F7B602372B} = {0351ADA4-0C32-4652-9BA0-41F7B602372B} {0351ADA4-0C32-4652-9BA0-41F7B602372B} = {0351ADA4-0C32-4652-9BA0-41F7B602372B}
{4BABF3FE-3451-42FD-873F-3C332E18DCEF} = {4BABF3FE-3451-42FD-873F-3C332E18DCEF} {4BABF3FE-3451-42FD-873F-3C332E18DCEF} = {4BABF3FE-3451-42FD-873F-3C332E18DCEF}
{4D971245-7A70-41D5-BAA0-DDB5684CAF51} = {4D971245-7A70-41D5-BAA0-DDB5684CAF51} {4D971245-7A70-41D5-BAA0-DDB5684CAF51} = {4D971245-7A70-41D5-BAA0-DDB5684CAF51}
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D} = {500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}
{5043CECE-E6A7-4867-9CBE-02D27D83747A} = {5043CECE-E6A7-4867-9CBE-02D27D83747A} {5043CECE-E6A7-4867-9CBE-02D27D83747A} = {5043CECE-E6A7-4867-9CBE-02D27D83747A}
{59BD9891-3837-438A-958D-ADC7F91F6F7E} = {59BD9891-3837-438A-958D-ADC7F91F6F7E} {59BD9891-3837-438A-958D-ADC7F91F6F7E} = {59BD9891-3837-438A-958D-ADC7F91F6F7E}
{5A1DB2F0-0715-4B3B-98E6-79BC41540045} = {5A1DB2F0-0715-4B3B-98E6-79BC41540045} {5A1DB2F0-0715-4B3B-98E6-79BC41540045} = {5A1DB2F0-0715-4B3B-98E6-79BC41540045}
@@ -500,6 +501,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RegistryPreviewExt", "src\m
EndProject EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RegistryPreview", "RegistryPreview", "{929C1324-22E8-4412-A9A8-80E85F3985A5}" Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "RegistryPreview", "RegistryPreview", "{929C1324-22E8-4412-A9A8-80E85F3985A5}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.PowerToys.Run.Plugin.PowerToys", "src\modules\launcher\Plugins\Microsoft.PowerToys.Run.Plugin.PowerToys\Microsoft.PowerToys.Run.Plugin.PowerToys.csproj", "{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}"
EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|ARM64 = Debug|ARM64 Debug|ARM64 = Debug|ARM64
@@ -2096,6 +2099,18 @@ Global
{697C6AF9-0A48-49A9-866C-67DA12384015}.Release|x64.Build.0 = Release|x64 {697C6AF9-0A48-49A9-866C-67DA12384015}.Release|x64.Build.0 = Release|x64
{697C6AF9-0A48-49A9-866C-67DA12384015}.Release|x86.ActiveCfg = Release|x64 {697C6AF9-0A48-49A9-866C-67DA12384015}.Release|x86.ActiveCfg = Release|x64
{697C6AF9-0A48-49A9-866C-67DA12384015}.Release|x86.Build.0 = Release|x64 {697C6AF9-0A48-49A9-866C-67DA12384015}.Release|x86.Build.0 = Release|x64
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Debug|ARM64.ActiveCfg = Debug|ARM64
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Debug|ARM64.Build.0 = Debug|ARM64
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Debug|x64.ActiveCfg = Debug|x64
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Debug|x64.Build.0 = Debug|x64
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Debug|x86.ActiveCfg = Debug|x64
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Debug|x86.Build.0 = Debug|x64
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Release|ARM64.ActiveCfg = Release|ARM64
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Release|ARM64.Build.0 = Release|ARM64
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Release|x64.ActiveCfg = Release|x64
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Release|x64.Build.0 = Release|x64
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Release|x86.ActiveCfg = Release|x64
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D}.Release|x86.Build.0 = Release|x64
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
@@ -2273,6 +2288,7 @@ Global
{FD86C06A-FB54-4D5E-9831-1CDADF60D45F} = {929C1324-22E8-4412-A9A8-80E85F3985A5} {FD86C06A-FB54-4D5E-9831-1CDADF60D45F} = {929C1324-22E8-4412-A9A8-80E85F3985A5}
{697C6AF9-0A48-49A9-866C-67DA12384015} = {929C1324-22E8-4412-A9A8-80E85F3985A5} {697C6AF9-0A48-49A9-866C-67DA12384015} = {929C1324-22E8-4412-A9A8-80E85F3985A5}
{929C1324-22E8-4412-A9A8-80E85F3985A5} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC} {929C1324-22E8-4412-A9A8-80E85F3985A5} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
{500DED3E-CFB5-4ED5-ACC6-02B3D6DC336D} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
EndGlobalSection EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0} SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}

View File

@@ -570,6 +570,9 @@
<Directory Id="OneNotePluginFolder" Name="OneNote"> <Directory Id="OneNotePluginFolder" Name="OneNote">
<Directory Id="OneNoteImagesFolder" Name="Images" /> <Directory Id="OneNoteImagesFolder" Name="Images" />
</Directory> </Directory>
<Directory Id="PowerToysPluginFolder" Name="PowerToys">
<Directory Id="PowerToysImagesFolder" Name="Images" />
</Directory>
<Directory Id="RegistryPluginFolder" Name="Registry"> <Directory Id="RegistryPluginFolder" Name="Registry">
<Directory Id="RegistryImagesFolder" Name="Images" /> <Directory Id="RegistryImagesFolder" Name="Images" />
</Directory> </Directory>

View File

@@ -11,7 +11,7 @@
<Fragment> <Fragment>
<!-- Resource directories should be added only if the installer is built on the build farm --> <!-- Resource directories should be added only if the installer is built on the build farm -->
<?ifdef env.IsPipeline?> <?ifdef env.IsPipeline?>
<?foreach ParentDirectory in LauncherInstallFolder;FancyZonesInstallFolder;ImageResizerInstallFolder;ColorPickerInstallFolder;FileExplorerPreviewInstallFolder;HistoryPluginFolder;CalculatorPluginFolder;FolderPluginFolder;ProgramPluginFolder;ShellPluginFolder;IndexerPluginFolder;UnitConverterPluginFolder;UriPluginFolder;WindowWalkerPluginFolder;OneNotePluginFolder;RegistryPluginFolder;VSCodeWorkspacesPluginFolder;ServicePluginFolder;SystemPluginFolder;TimeDatePluginFolder;WindowsSettingsPluginFolder;WindowsTerminalPluginFolder;WebSearchPluginFolder?> <?foreach ParentDirectory in LauncherInstallFolder;FancyZonesInstallFolder;ImageResizerInstallFolder;ColorPickerInstallFolder;FileExplorerPreviewInstallFolder;HistoryPluginFolder;CalculatorPluginFolder;FolderPluginFolder;ProgramPluginFolder;ShellPluginFolder;IndexerPluginFolder;UnitConverterPluginFolder;UriPluginFolder;WindowWalkerPluginFolder;OneNotePluginFolder;RegistryPluginFolder;VSCodeWorkspacesPluginFolder;ServicePluginFolder;SystemPluginFolder;TimeDatePluginFolder;WindowsSettingsPluginFolder;WindowsTerminalPluginFolder;WebSearchPluginFolder;PowerToysPluginFolder?>
<DirectoryRef Id="$(var.ParentDirectory)"> <DirectoryRef Id="$(var.ParentDirectory)">
<!-- Resource file directories --> <!-- Resource file directories -->
<?foreach Language in $(var.LocLanguageList)?> <?foreach Language in $(var.LocLanguageList)?>

View File

@@ -100,6 +100,11 @@
<?define WinTermImagesCmpFiles=?> <?define WinTermImagesCmpFiles=?>
<?define WinTermImagesCmpFilesPath=$(var.BinDir)modules\launcher\Plugins\WindowsTerminal\Images\?> <?define WinTermImagesCmpFilesPath=$(var.BinDir)modules\launcher\Plugins\WindowsTerminal\Images\?>
<?define PowerToysCmpFiles=?>
<?define PowerToysCmpFilesPath=$(var.BinDir)modules\launcher\Plugins\PowerToys\?>
<?define PowerToysImagesCmpFiles=?>
<?define PowerToysImagesCmpFilesPath=$(var.BinDir)modules\launcher\Plugins\PowerToys\Images\?>
<Fragment> <Fragment>
<Component Id="launcherShortcutComponent" Directory="LauncherInstallFolder" > <Component Id="launcherShortcutComponent" Directory="LauncherInstallFolder" >
<!-- Toast Notification AUMID --> <!-- Toast Notification AUMID -->
@@ -311,6 +316,17 @@
<!--WinTermImagesCmpFiles_Component_Def--> <!--WinTermImagesCmpFiles_Component_Def-->
</DirectoryRef> </DirectoryRef>
<!-- PowerToys Plugin -->
<DirectoryRef Id="PowerToysPluginFolder" FileSource="$(var.PowerToysCmpFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--PowerToysCmpFiles_Component_Def-->
</DirectoryRef>
<DirectoryRef Id="PowerToysImagesFolder" FileSource="$(var.PowerToysImagesCmpFilesPath)">
<!-- Generated by generateFileComponents.ps1 -->
<!--PowerToysImagesCmpFiles_Component_Def-->
</DirectoryRef>
<ComponentGroup Id="RunComponentGroup"> <ComponentGroup Id="RunComponentGroup">
<Component Id="RemoveLauncherFolder" Guid="3FFDC0B6-82BC-4C57-AEB1-C710DB108C23" Directory="LauncherInstallFolder" > <Component Id="RemoveLauncherFolder" Guid="3FFDC0B6-82BC-4C57-AEB1-C710DB108C23" Directory="LauncherInstallFolder" >
<RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components"> <RegistryKey Root="$(var.RegistryScope)" Key="Software\Classes\powertoys\components">
@@ -355,6 +371,8 @@
<RemoveFolder Id="RemoveFolderWindowsSettingsImagesFolder" Directory="WindowsSettingsImagesFolder" On="uninstall"/> <RemoveFolder Id="RemoveFolderWindowsSettingsImagesFolder" Directory="WindowsSettingsImagesFolder" On="uninstall"/>
<RemoveFolder Id="RemoveFolderWindowsTerminalPluginFolder" Directory="WindowsTerminalPluginFolder" On="uninstall"/> <RemoveFolder Id="RemoveFolderWindowsTerminalPluginFolder" Directory="WindowsTerminalPluginFolder" On="uninstall"/>
<RemoveFolder Id="RemoveFolderWindowsTerminalImagesFolder" Directory="WindowsTerminalImagesFolder" On="uninstall"/> <RemoveFolder Id="RemoveFolderWindowsTerminalImagesFolder" Directory="WindowsTerminalImagesFolder" On="uninstall"/>
<RemoveFolder Id="RemoveFolderPowerToysPluginFolder" Directory="PowerToysPluginFolder" On="uninstall"/>
<RemoveFolder Id="RemoveFolderPowerToysImagesFolder" Directory="PowerToysImagesFolder" On="uninstall"/>
</Component> </Component>
<ComponentRef Id="launcherShortcutComponent" /> <ComponentRef Id="launcherShortcutComponent" />
</ComponentGroup> </ComponentGroup>

View File

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation // Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license. // The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
@@ -24,6 +24,8 @@ namespace Common.UI
ShortcutGuide, ShortcutGuide,
VideoConference, VideoConference,
Hosts, Hosts,
MeasureTool,
PowerOCR,
RegistryPreview, RegistryPreview,
} }
@@ -57,6 +59,10 @@ namespace Common.UI
return "VideoConference"; return "VideoConference";
case SettingsWindow.Hosts: case SettingsWindow.Hosts:
return "Hosts"; return "Hosts";
case SettingsWindow.MeasureTool:
return "MeasureTool";
case SettingsWindow.PowerOCR:
return "PowerOCR";
case SettingsWindow.RegistryPreview: case SettingsWindow.RegistryPreview:
return "RegistryPreview"; return "RegistryPreview";
default: default:

View File

@@ -188,7 +188,7 @@ public
} }
static String ^ FZEToggleEvent() { static String ^ FZEToggleEvent() {
return gcnew String(CommonSharedConstants::FANCY_ZONES_EDITOR_TOGGLE_EVENT); return gcnew String(CommonSharedConstants::FANCY_ZONES_EDITOR_TOGGLE_EVENT);
} }
static String ^ ColorPickerSendSettingsTelemetryEvent() { static String ^ ColorPickerSendSettingsTelemetryEvent() {
@@ -242,5 +242,13 @@ public
static String ^ SvgPreviewResizeEvent() { static String ^ SvgPreviewResizeEvent() {
return gcnew String(CommonSharedConstants::SVG_PREVIEW_RESIZE_EVENT); return gcnew String(CommonSharedConstants::SVG_PREVIEW_RESIZE_EVENT);
} }
static String ^ ShowHostsSharedEvent() {
return gcnew String(CommonSharedConstants::SHOW_HOSTS_EVENT);
}
static String ^ ShowHostsAdminSharedEvent() {
return gcnew String(CommonSharedConstants::SHOW_HOSTS_ADMIN_EVENT);
}
}; };
} }

View File

@@ -34,6 +34,10 @@ namespace CommonSharedConstants
const wchar_t FANCY_ZONES_EDITOR_TOGGLE_EVENT[] = L"Local\\FancyZones-ToggleEditorEvent-1e174338-06a3-472b-874d-073b21c62f14"; const wchar_t FANCY_ZONES_EDITOR_TOGGLE_EVENT[] = L"Local\\FancyZones-ToggleEditorEvent-1e174338-06a3-472b-874d-073b21c62f14";
const wchar_t SHOW_HOSTS_EVENT[] = L"Local\\Hosts-ShowHostsEvent-5a0c0aae-5ff5-40f5-95c2-20e37ed671f0";
const wchar_t SHOW_HOSTS_ADMIN_EVENT[] = L"Local\\Hosts-ShowHostsAdminEvent-60ff44e2-efd3-43bf-928a-f4d269f98bec";
// Path to the event used by Awake // Path to the event used by Awake
const wchar_t AWAKE_EXIT_EVENT[] = L"Local\\PowerToysAwakeExitEvent-c0d5e305-35fc-4fb5-83ec-f6070cfaf7fe"; const wchar_t AWAKE_EXIT_EVENT[] = L"Local\\PowerToysAwakeExitEvent-c0d5e305-35fc-4fb5-83ec-f6070cfaf7fe";

View File

@@ -7,6 +7,8 @@
#include "Generated Files/resource.h" #include "Generated Files/resource.h"
#include <shellapi.h> #include <shellapi.h>
#include <common/interop/shared_constants.h>
#include <common/utils/EventWaiter.h>
#include <common/utils/resources.h> #include <common/utils/resources.h>
#include <common/utils/winapi_error.h> #include <common/utils/winapi_error.h>
#include <common/SettingsAPI/settings_objects.h> #include <common/SettingsAPI/settings_objects.h>
@@ -49,6 +51,10 @@ private:
HANDLE m_hProcess; HANDLE m_hProcess;
HANDLE m_hShowEvent;
HANDLE m_hShowAdminEvent;
bool is_process_running() bool is_process_running()
{ {
return WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT; return WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT;
@@ -104,11 +110,55 @@ private:
} }
public: public:
EventWaiter m_showEventWaiter;
EventWaiter m_showAdminEventWaiter;
HostsModuleInterface() HostsModuleInterface()
{ {
app_name = GET_RESOURCE_STRING(IDS_HOSTS_NAME); app_name = GET_RESOURCE_STRING(IDS_HOSTS_NAME);
app_key = ModuleKey; app_key = ModuleKey;
LoggerHelpers::init_logger(app_key, L"ModuleInterface", LogSettings::hostsLoggerName); LoggerHelpers::init_logger(app_key, L"ModuleInterface", LogSettings::hostsLoggerName);
m_hShowEvent = CreateDefaultEvent(CommonSharedConstants::SHOW_HOSTS_EVENT);
if (!m_hShowEvent)
{
Logger::error(L"Failed to create show hosts event");
auto message = get_last_error_message(GetLastError());
if (message.has_value())
{
Logger::error(message.value());
}
}
m_hShowAdminEvent = CreateDefaultEvent(CommonSharedConstants::SHOW_HOSTS_ADMIN_EVENT);
if (!m_hShowEvent)
{
Logger::error(L"Failed to create show hosts admin event");
auto message = get_last_error_message(GetLastError());
if (message.has_value())
{
Logger::error(message.value());
}
}
m_showEventWaiter = EventWaiter(CommonSharedConstants::SHOW_HOSTS_EVENT, [&](int err)
{
if (m_enabled && err == ERROR_SUCCESS)
{
Logger::trace(L"{} event was signaled", CommonSharedConstants::SHOW_HOSTS_EVENT);
launch_process(false);
}
});
m_showAdminEventWaiter = EventWaiter(CommonSharedConstants::SHOW_HOSTS_ADMIN_EVENT, [&](int err)
{
if (m_enabled && err == ERROR_SUCCESS)
{
Logger::trace(L"{} event was signaled", CommonSharedConstants::SHOW_HOSTS_ADMIN_EVENT);
launch_process(true);
}
});
} }
~HostsModuleInterface() ~HostsModuleInterface()
@@ -120,6 +170,19 @@ public:
virtual void destroy() override virtual void destroy() override
{ {
Logger::trace("HostsModuleInterface::destroy()"); Logger::trace("HostsModuleInterface::destroy()");
if (m_hShowEvent)
{
CloseHandle(m_hShowEvent);
m_hShowEvent = nullptr;
}
if (m_hShowAdminEvent)
{
CloseHandle(m_hShowAdminEvent);
m_hShowAdminEvent = nullptr;
}
delete this; delete this;
} }
@@ -194,6 +257,16 @@ public:
Logger::trace("HostsModuleInterface::disable()"); Logger::trace("HostsModuleInterface::disable()");
if (m_enabled) if (m_enabled)
{ {
if (m_hShowEvent)
{
ResetEvent(m_hShowEvent);
}
if (m_hShowAdminEvent)
{
ResetEvent(m_hShowAdminEvent);
}
TerminateProcess(m_hProcess, 1); TerminateProcess(m_hProcess, 1);
} }

View File

@@ -0,0 +1,96 @@
// 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.Collections.Generic;
using System.Threading;
using System.Windows.Input;
using Common.UI;
using interop;
using Microsoft.PowerToys.Run.Plugin.PowerToys.Properties;
using Wox.Infrastructure;
using Wox.Plugin;
namespace Microsoft.PowerToys.Run.Plugin.PowerToys.Components
{
public class Utility
{
public UtilityKey Key { get; }
public string Name { get; }
public bool Enabled { get; private set; }
public Utility(UtilityKey key, string name, bool enabled)
{
Key = key;
Name = name;
Enabled = enabled;
}
public Result CreateResult(MatchResult matchResult)
{
return new Result
{
Title = Name,
SubTitle = Resources.Subtitle_Powertoys_Utility,
IcoPath = UtilityHelper.GetIcoPath(Key),
Action = UtilityHelper.GetAction(Key),
ContextData = this,
Score = matchResult.Score,
TitleHighlightData = matchResult.MatchData,
};
}
public List<ContextMenuResult> CreateContextMenuResults()
{
var results = new List<ContextMenuResult>();
if (Key == UtilityKey.Hosts)
{
results.Add(new ContextMenuResult
{
Title = Resources.Action_Run_As_Administrator,
Glyph = "\xE7EF",
FontFamily = "Segoe MDL2 Assets",
AcceleratorKey = System.Windows.Input.Key.Enter,
AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,
Action = _ =>
{
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowHostsAdminSharedEvent()))
{
eventHandle.Set();
}
return true;
},
});
}
var settingsWindow = UtilityHelper.GetSettingsWindow(Key);
if (settingsWindow.HasValue)
{
results.Add(new ContextMenuResult
{
Title = Resources.Action_Open_Settings,
Glyph = "\xE713",
FontFamily = "Segoe MDL2 Assets",
AcceleratorKey = System.Windows.Input.Key.S,
AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift,
Action = _ =>
{
SettingsDeepLink.OpenSettings(settingsWindow.Value);
return true;
},
});
}
return results;
}
public void Enable(bool enabled)
{
Enabled = enabled;
}
}
}

View File

@@ -0,0 +1,115 @@
// 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.Threading;
using Common.UI;
using interop;
using Wox.Plugin;
namespace Microsoft.PowerToys.Run.Plugin.PowerToys.Components
{
public static class UtilityHelper
{
public static string GetIcoPath(UtilityKey key)
{
return key switch
{
UtilityKey.ColorPicker => "Images/ColorPicker.png",
UtilityKey.FancyZones => "Images/FancyZones.png",
UtilityKey.Hosts => "Images/Hosts.png",
UtilityKey.MeasureTool => "Images/ScreenRuler.png",
UtilityKey.PowerOCR => "Images/PowerOcr.png",
UtilityKey.ShortcutGuide => "Images/ShortcutGuide.png",
UtilityKey.RegistryPreview => "Images/RegistryPreview.png",
_ => null,
};
}
public static SettingsDeepLink.SettingsWindow? GetSettingsWindow(UtilityKey key)
{
return key switch
{
UtilityKey.ColorPicker => SettingsDeepLink.SettingsWindow.ColorPicker,
UtilityKey.FancyZones => SettingsDeepLink.SettingsWindow.FancyZones,
UtilityKey.Hosts => SettingsDeepLink.SettingsWindow.Hosts,
UtilityKey.MeasureTool => SettingsDeepLink.SettingsWindow.MeasureTool,
UtilityKey.PowerOCR => SettingsDeepLink.SettingsWindow.PowerOCR,
UtilityKey.ShortcutGuide => SettingsDeepLink.SettingsWindow.ShortcutGuide,
UtilityKey.RegistryPreview => SettingsDeepLink.SettingsWindow.RegistryPreview,
_ => null,
};
}
public static Func<ActionContext, bool> GetAction(UtilityKey key)
{
return (context) =>
{
switch (key)
{
case UtilityKey.ColorPicker: // Launch ColorPicker
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowColorPickerSharedEvent()))
{
eventHandle.Set();
}
break;
case UtilityKey.FancyZones: // Launch FancyZones Editor
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.FZEToggleEvent()))
{
eventHandle.Set();
}
break;
case UtilityKey.Hosts: // Launch Hosts
{
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowHostsSharedEvent()))
{
eventHandle.Set();
}
}
break;
case UtilityKey.MeasureTool: // Launch Screen Ruler
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.MeasureToolTriggerEvent()))
{
eventHandle.Set();
}
break;
case UtilityKey.PowerOCR: // Launch Text Extractor
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShowPowerOCRSharedEvent()))
{
eventHandle.Set();
}
break;
case UtilityKey.ShortcutGuide: // Launch Shortcut Guide
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.ShortcutGuideTriggerEvent()))
{
eventHandle.Set();
}
break;
case UtilityKey.RegistryPreview: // Launch Registry Preview
using (var eventHandle = new EventWaitHandle(false, EventResetMode.AutoReset, Constants.RegistryPreviewTriggerEvent()))
{
eventHandle.Set();
}
break;
default:
break;
}
return true;
};
}
}
}

View File

@@ -0,0 +1,17 @@
// 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.
namespace Microsoft.PowerToys.Run.Plugin.PowerToys.Components
{
public enum UtilityKey
{
ColorPicker = 0,
FancyZones = 1,
Hosts = 2,
MeasureTool = 3,
PowerOCR = 4,
ShortcutGuide = 5,
RegistryPreview = 6,
}
}

View File

@@ -0,0 +1,148 @@
// 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.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using Microsoft.PowerToys.Run.Plugin.PowerToys.Components;
using Microsoft.PowerToys.Run.Plugin.PowerToys.Properties;
using Microsoft.PowerToys.Settings.UI.Library;
using PowerToys.GPOWrapper;
using Wox.Plugin.Logger;
namespace Microsoft.PowerToys.Run.Plugin.PowerToys
{
public class UtilityProvider : IDisposable
{
private const int MaxNumberOfRetry = 5;
private readonly List<Utility> _utilities;
private readonly FileSystemWatcher _watcher;
private readonly object _loadingSettingsLock = new();
private bool _disposed;
public UtilityProvider()
{
var settingsUtils = new SettingsUtils();
var generalSettings = settingsUtils.GetSettings<GeneralSettings>();
_utilities = new List<Utility>();
if (GPOWrapper.GetConfiguredColorPickerEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.ColorPicker, Resources.Color_Picker, generalSettings.Enabled.ColorPicker));
}
if (GPOWrapper.GetConfiguredFancyZonesEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.FancyZones, Resources.FancyZones_Editor, generalSettings.Enabled.FancyZones));
}
if (GPOWrapper.GetConfiguredHostsFileEditorEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.Hosts, Resources.Hosts_File_Editor, generalSettings.Enabled.Hosts));
}
if (GPOWrapper.GetConfiguredScreenRulerEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.MeasureTool, Resources.Screen_Ruler, generalSettings.Enabled.MeasureTool));
}
if (GPOWrapper.GetConfiguredTextExtractorEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.PowerOCR, Resources.Text_Extractor, generalSettings.Enabled.PowerOCR));
}
if (GPOWrapper.GetConfiguredShortcutGuideEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.ShortcutGuide, Resources.Shortcut_Guide, generalSettings.Enabled.ShortcutGuide));
}
if (GPOWrapper.GetConfiguredRegistryPreviewEnabledValue() != GpoRuleConfigured.Disabled)
{
_utilities.Add(new Utility(UtilityKey.RegistryPreview, Resources.Registry_Preview, generalSettings.Enabled.RegistryPreview));
}
_watcher = new FileSystemWatcher
{
Path = Path.GetDirectoryName(settingsUtils.GetSettingsFilePath()),
Filter = Path.GetFileName(settingsUtils.GetSettingsFilePath()),
NotifyFilter = NotifyFilters.LastWrite,
};
_watcher.Changed += (s, e) => ReloadUtilities();
_watcher.EnableRaisingEvents = true;
}
public IEnumerable<Utility> GetEnabledUtilities()
{
return _utilities.Where(u => u.Enabled);
}
private void ReloadUtilities()
{
lock (_loadingSettingsLock)
{
var retry = true;
var retryCount = 0;
while (retry)
{
try
{
retryCount++;
var settingsUtils = new SettingsUtils();
var generalSettings = settingsUtils.GetSettings<GeneralSettings>();
foreach (var u in _utilities)
{
switch (u.Key)
{
case UtilityKey.ColorPicker: u.Enable(generalSettings.Enabled.ColorPicker); break;
case UtilityKey.FancyZones: u.Enable(generalSettings.Enabled.FancyZones); break;
case UtilityKey.Hosts: u.Enable(generalSettings.Enabled.Hosts); break;
case UtilityKey.PowerOCR: u.Enable(generalSettings.Enabled.PowerOCR); break;
case UtilityKey.MeasureTool: u.Enable(generalSettings.Enabled.MeasureTool); break;
case UtilityKey.ShortcutGuide: u.Enable(generalSettings.Enabled.ShortcutGuide); break;
case UtilityKey.RegistryPreview: u.Enable(generalSettings.Enabled.RegistryPreview); break;
}
}
retry = false;
}
catch (Exception ex)
{
if (retryCount > MaxNumberOfRetry)
{
Log.Exception("Failed to read changed settings", ex, typeof(UtilityProvider));
retry = false;
}
Thread.Sleep(500);
}
}
}
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_watcher?.Dispose();
_disposed = true;
}
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 921 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 329 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 320 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -0,0 +1,74 @@
// 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.Collections.Generic;
using System.Linq;
using Microsoft.PowerToys.Run.Plugin.PowerToys.Components;
using Microsoft.PowerToys.Run.Plugin.PowerToys.Properties;
using Wox.Infrastructure;
using Wox.Plugin;
namespace Microsoft.PowerToys.Run.Plugin.PowerToys
{
public class Main : IPlugin, IPluginI18n, IContextMenu, IDisposable
{
private UtilityProvider _utilityProvider;
private bool _disposed;
public string Name => Resources.Plugin_Name;
public string Description => Resources.Plugin_Description;
public string GetTranslatedPluginTitle() => Resources.Plugin_Name;
public string GetTranslatedPluginDescription() => Resources.Plugin_Description;
public void Init(PluginInitContext context)
{
_utilityProvider = new UtilityProvider();
}
public List<ContextMenuResult> LoadContextMenus(Result selectedResult)
{
return selectedResult.ContextData is Utility u
? u.CreateContextMenuResults()
: new List<ContextMenuResult>();
}
public List<Result> Query(Query query)
{
var results = new List<Result>();
foreach (var utility in _utilityProvider.GetEnabledUtilities())
{
var matchResult = StringMatcher.FuzzySearch(query.Search, utility.Name);
if (string.IsNullOrWhiteSpace(query.Search) || matchResult.Score > 0)
{
results.Add(utility.CreateResult(matchResult));
}
}
return results.OrderBy(r => r.Title).ToList();
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_utilityProvider?.Dispose();
_disposed = true;
}
}
}
}
}

View File

@@ -0,0 +1,96 @@
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\..\Version.props" />
<PropertyGroup>
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<RootNamespace>Microsoft.PowerToys.Run.Plugin.PowerToys</RootNamespace>
<AssemblyName>Microsoft.PowerToys.Run.Plugin.PowerToys</AssemblyName>
<Version>$(Version).0</Version>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
<GenerateSatelliteAssembliesForCore>true</GenerateSatelliteAssembliesForCore>
<OutputPath>..\..\..\..\..\$(Platform)\$(Configuration)\modules\launcher\Plugins\PowerToys\</OutputPath>
</PropertyGroup>
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
<PropertyGroup>
<CsWinRTIncludes>PowerToys.GPOWrapper</CsWinRTIncludes>
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
<Optimize>false</Optimize>
<DebugType>full</DebugType>
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<DefineConstants>TRACE</DefineConstants>
<Optimize>true</Optimize>
<DebugType>pdbonly</DebugType>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
<ProjectReference Include="..\..\Wox.Infrastructure\Wox.Infrastructure.csproj" />
<ProjectReference Include="..\..\Wox.Plugin\Wox.Plugin.csproj" />
</ItemGroup>
<ItemGroup>
<None Include="plugin.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWinRT" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Update="Images\ColorPicker.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\FancyZones.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\Hosts.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\PowerOcr.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\PowerToys.dark.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\PowerToys.light.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\RegistryPreview.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\ScreenRuler.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Images\ShortcutGuide.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -0,0 +1,171 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Microsoft.PowerToys.Run.Plugin.PowerToys.Properties {
using System;
/// <summary>
/// A strongly-typed resource class, for looking up localized strings, etc.
/// </summary>
// This class was auto-generated by the StronglyTypedResourceBuilder
// class via a tool like ResGen or Visual Studio.
// To add or remove a member, edit your .ResX file then rerun ResGen
// with the /str option, or rebuild your VS project.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resources {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resources() {
}
/// <summary>
/// Returns the cached ResourceManager instance used by this class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.PowerToys.Run.Plugin.PowerToys.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// Overrides the current thread's CurrentUICulture property for all
/// resource lookups using this strongly typed resource class.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// Looks up a localized string similar to Open settings (Ctrl+Shift+S).
/// </summary>
internal static string Action_Open_Settings {
get {
return ResourceManager.GetString("Action_Open_Settings", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Run as administrator (Ctrl+Shift+Enter).
/// </summary>
internal static string Action_Run_As_Administrator {
get {
return ResourceManager.GetString("Action_Run_As_Administrator", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Color Picker.
/// </summary>
internal static string Color_Picker {
get {
return ResourceManager.GetString("Color_Picker", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to FancyZones Editor.
/// </summary>
internal static string FancyZones_Editor {
get {
return ResourceManager.GetString("FancyZones_Editor", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Hosts File Editor.
/// </summary>
internal static string Hosts_File_Editor {
get {
return ResourceManager.GetString("Hosts_File_Editor", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Open PowerToys utilities and settings..
/// </summary>
internal static string Plugin_Description {
get {
return ResourceManager.GetString("Plugin_Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to PowerToys.
/// </summary>
internal static string Plugin_Name {
get {
return ResourceManager.GetString("Plugin_Name", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Registry Preview.
/// </summary>
internal static string Registry_Preview {
get {
return ResourceManager.GetString("Registry_Preview", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Screen Ruler.
/// </summary>
internal static string Screen_Ruler {
get {
return ResourceManager.GetString("Screen_Ruler", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Shortcut Guide.
/// </summary>
internal static string Shortcut_Guide {
get {
return ResourceManager.GetString("Shortcut_Guide", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to PowerToys Utility.
/// </summary>
internal static string Subtitle_Powertoys_Utility {
get {
return ResourceManager.GetString("Subtitle_Powertoys_Utility", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Text Extractor.
/// </summary>
internal static string Text_Extractor {
get {
return ResourceManager.GetString("Text_Extractor", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,163 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Action_Open_Settings" xml:space="preserve">
<value>Open settings (Ctrl+Shift+S)</value>
</data>
<data name="Action_Run_As_Administrator" xml:space="preserve">
<value>Run as administrator (Ctrl+Shift+Enter)</value>
</data>
<data name="Color_Picker" xml:space="preserve">
<value>Color Picker</value>
<comment>"Color Picker" is the name of the utility</comment>
</data>
<data name="FancyZones_Editor" xml:space="preserve">
<value>FancyZones Editor</value>
<comment>"FancyZones" is the name of the utility</comment>
</data>
<data name="Hosts_File_Editor" xml:space="preserve">
<value>Hosts File Editor</value>
<comment>"Hosts File Editor" is the name of the utility</comment>
</data>
<data name="Plugin_Description" xml:space="preserve">
<value>Open PowerToys utilities and settings.</value>
</data>
<data name="Plugin_Name" xml:space="preserve">
<value>PowerToys</value>
</data>
<data name="Registry_Preview" xml:space="preserve">
<value>Registry Preview</value>
<comment>"Registry Preview" is the name of the utility</comment>
</data>
<data name="Screen_Ruler" xml:space="preserve">
<value>Screen Ruler</value>
<comment>"Screen Ruler" is the name of the utility</comment>
</data>
<data name="Shortcut_Guide" xml:space="preserve">
<value>Shortcut Guide</value>
<comment>"Shortcut Guide" is the name of the utility</comment>
</data>
<data name="Subtitle_Powertoys_Utility" xml:space="preserve">
<value>PowerToys Utility</value>
</data>
<data name="Text_Extractor" xml:space="preserve">
<value>Text Extractor</value>
<comment>"Text Extractor" is the name of the utility</comment>
</data>
</root>

View File

@@ -0,0 +1,14 @@
{
"ID": "29DD65DB28C84A37BDEF1D2B43DA368B",
"Disabled": true,
"ActionKeyword": "@",
"IsGlobal": true,
"Name": "PowerToys",
"Author": "davidegiacometti",
"Version": "1.0.0",
"Language": "csharp",
"Website": "https://aka.ms/powertoys",
"ExecuteFileName": "Microsoft.PowerToys.Run.Plugin.PowerToys.dll",
"IcoPathDark": "Images\\PowerToys.dark.png",
"IcoPathLight": "Images\\PowerToys.light.png"
}

View File

@@ -586,7 +586,15 @@ void open_settings_window(std::optional<std::wstring> settings_window, bool show
// bring_settings_to_front(); // bring_settings_to_front();
if (current_settings_ipc) if (current_settings_ipc)
{ {
current_settings_ipc->send(L"{\"ShowYourself\":\"main_page\"}"); if (settings_window.has_value())
{
std::wstring msg = L"{\"ShowYourself\":\"" + settings_window.value() + L"\"}";
current_settings_ipc->send(msg);
}
else
{
current_settings_ipc->send(L"{\"ShowYourself\":\"Overview\"}");
}
} }
} }
} }
@@ -657,6 +665,10 @@ std::string ESettingsWindowNames_to_string(ESettingsWindowNames value)
return "VideoConference"; return "VideoConference";
case ESettingsWindowNames::Hosts: case ESettingsWindowNames::Hosts:
return "Hosts"; return "Hosts";
case ESettingsWindowNames::MeasureTool:
return "MeasureTool";
case ESettingsWindowNames::PowerOCR:
return "PowerOCR";
case ESettingsWindowNames::RegistryPreview: case ESettingsWindowNames::RegistryPreview:
return "RegistryPreview"; return "RegistryPreview";
default: default:
@@ -722,6 +734,14 @@ ESettingsWindowNames ESettingsWindowNames_from_string(std::string value)
{ {
return ESettingsWindowNames::Hosts; return ESettingsWindowNames::Hosts;
} }
else if (value == "MeasureTool")
{
return ESettingsWindowNames::MeasureTool;
}
else if (value == "PowerOCR")
{
return ESettingsWindowNames::PowerOCR;
}
else if (value == "RegistryPreview") else if (value == "RegistryPreview")
{ {
return ESettingsWindowNames::RegistryPreview; return ESettingsWindowNames::RegistryPreview;

View File

@@ -17,6 +17,8 @@ enum class ESettingsWindowNames
ShortcutGuide, ShortcutGuide,
VideoConference, VideoConference,
Hosts, Hosts,
MeasureTool,
PowerOCR,
RegistryPreview, RegistryPreview,
}; };

View File

@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation // Copyright (c) Microsoft Corporation
// The Microsoft Corporation licenses this file to you under the MIT license. // The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // See the LICENSE file in the project root for more information.
@@ -12,12 +12,12 @@ using ManagedCommon;
using Microsoft.PowerToys.Settings.UI.Helpers; using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Telemetry.Events; using Microsoft.PowerToys.Settings.UI.Library.Telemetry.Events;
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
using Microsoft.PowerToys.Settings.UI.Views; using Microsoft.PowerToys.Settings.UI.Views;
using Microsoft.PowerToys.Telemetry; using Microsoft.PowerToys.Telemetry;
using Microsoft.UI.Xaml; using Microsoft.UI.Xaml;
using Windows.UI.Popups; using Windows.UI.Popups;
using WinRT.Interop; using WinRT.Interop;
using WinUIEx;
namespace Microsoft.PowerToys.Settings.UI namespace Microsoft.PowerToys.Settings.UI
{ {
@@ -82,7 +82,6 @@ namespace Microsoft.PowerToys.Settings.UI
if (settingsWindow == null) if (settingsWindow == null)
{ {
settingsWindow = new MainWindow(IsDarkTheme()); settingsWindow = new MainWindow(IsDarkTheme());
type = typeof(GeneralPage);
} }
settingsWindow.Activate(); settingsWindow.Activate();
@@ -132,31 +131,8 @@ namespace Microsoft.PowerToys.Settings.UI
if (containsSettingsWindow) if (containsSettingsWindow)
{ {
// open specific window // Open specific window
switch (cmdArgs[currentArgumentIndex]) StartupPage = GetPage(cmdArgs[currentArgumentIndex]);
{
case "Overview": StartupPage = typeof(Views.GeneralPage); break;
case "AlwaysOnTop": StartupPage = typeof(Views.AlwaysOnTopPage); break;
case "Awake": StartupPage = typeof(Views.AwakePage); break;
case "ColorPicker": StartupPage = typeof(Views.ColorPickerPage); break;
case "FancyZones": StartupPage = typeof(Views.FancyZonesPage); break;
case "FileLocksmith": StartupPage = typeof(Views.FileLocksmithPage); break;
case "Run": StartupPage = typeof(Views.PowerLauncherPage); break;
case "ImageResizer": StartupPage = typeof(Views.ImageResizerPage); break;
case "KBM": StartupPage = typeof(Views.KeyboardManagerPage); break;
case "MouseUtils": StartupPage = typeof(Views.MouseUtilsPage); break;
case "PowerRename": StartupPage = typeof(Views.PowerRenamePage); break;
case "QuickAccent": StartupPage = typeof(Views.PowerAccentPage); break;
case "FileExplorer": StartupPage = typeof(Views.PowerPreviewPage); break;
case "ShortcutGuide": StartupPage = typeof(Views.ShortcutGuidePage); break;
case "TextExtractor": StartupPage = typeof(Views.PowerOcrPage); break;
case "VideoConference": StartupPage = typeof(Views.VideoConferencePage); break;
case "MeasureTool": StartupPage = typeof(Views.MeasureToolPage); break;
case "Hosts": StartupPage = typeof(Views.HostsPage); break;
case "RegistryPreview": StartupPage = typeof(Views.RegistryPreviewPage); break;
case "PastePlain": StartupPage = typeof(Views.PastePlainPage); break;
default: Debug.Assert(false, "Unexpected SettingsWindow argument value"); break;
}
currentArgumentIndex++; currentArgumentIndex++;
} }
@@ -189,6 +165,10 @@ namespace Microsoft.PowerToys.Settings.UI
settingsWindow = new MainWindow(isDark); settingsWindow = new MainWindow(isDark);
settingsWindow.Activate(); settingsWindow.Activate();
settingsWindow.NavigateToSection(StartupPage); settingsWindow.NavigateToSection(StartupPage);
// https://github.com/microsoft/microsoft-ui-xaml/issues/7595 - Activate doesn't bring window to the foreground
// Need to call SetForegroundWindow to actually gain focus.
Utils.BecomeForegroundWindow(settingsWindow.GetWindowHandle());
} }
else else
{ {
@@ -364,5 +344,36 @@ namespace Microsoft.PowerToys.Settings.UI
{ {
flyoutWindow = null; flyoutWindow = null;
} }
public static Type GetPage(string settingWindow)
{
switch (settingWindow)
{
case "Overview": return typeof(GeneralPage);
case "AlwaysOnTop": return typeof(AlwaysOnTopPage);
case "Awake": return typeof(AwakePage);
case "ColorPicker": return typeof(ColorPickerPage);
case "FancyZones": return typeof(FancyZonesPage);
case "FileLocksmith": return typeof(FileLocksmithPage);
case "Run": return typeof(PowerLauncherPage);
case "ImageResizer": return typeof(ImageResizerPage);
case "KBM": return typeof(KeyboardManagerPage);
case "MouseUtils": return typeof(MouseUtilsPage);
case "PowerRename": return typeof(PowerRenamePage);
case "QuickAccent": return typeof(PowerAccentPage);
case "FileExplorer": return typeof(PowerPreviewPage);
case "ShortcutGuide": return typeof(ShortcutGuidePage);
case "PowerOCR": return typeof(PowerOcrPage);
case "VideoConference": return typeof(VideoConferencePage);
case "MeasureTool": return typeof(MeasureToolPage);
case "Hosts": return typeof(HostsPage);
case "RegistryPreview": return typeof(RegistryPreviewPage);
case "PastePlain": return typeof(PastePlainPage);
default:
// Fallback to general
Debug.Assert(false, "Unexpected SettingsWindow argument value");
return typeof(GeneralPage);
}
}
} }
} }

View File

@@ -1,4 +1,4 @@
<winuiex:WindowEx <winuiex:WindowEx
x:Class="Microsoft.PowerToys.Settings.UI.MainWindow" x:Class="Microsoft.PowerToys.Settings.UI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

View File

@@ -7,7 +7,6 @@ using ManagedCommon;
using Microsoft.PowerLauncher.Telemetry; using Microsoft.PowerLauncher.Telemetry;
using Microsoft.PowerToys.Settings.UI.Helpers; using Microsoft.PowerToys.Settings.UI.Helpers;
using Microsoft.PowerToys.Settings.UI.Library; using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Utilities;
using Microsoft.PowerToys.Settings.UI.Views; using Microsoft.PowerToys.Settings.UI.Views;
using Microsoft.PowerToys.Telemetry; using Microsoft.PowerToys.Telemetry;
using Microsoft.UI; using Microsoft.UI;
@@ -76,10 +75,10 @@ namespace Microsoft.PowerToys.Settings.UI
}); });
// open main window // open main window
ShellPage.SetOpenMainWindowCallback(() => ShellPage.SetOpenMainWindowCallback(type =>
{ {
this.DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal, () => DispatcherQueue.TryEnqueue(Microsoft.UI.Dispatching.DispatcherQueuePriority.Normal, () =>
App.OpenSettingsWindow(typeof(GeneralPage))); App.OpenSettingsWindow(type));
}); });
// open main window // open main window

View File

@@ -30,7 +30,7 @@ namespace Microsoft.PowerToys.Settings.UI.Views
/// <summary> /// <summary>
/// Declaration for the opening main window callback function. /// Declaration for the opening main window callback function.
/// </summary> /// </summary>
public delegate void MainOpeningCallback(); public delegate void MainOpeningCallback(Type type);
/// <summary> /// <summary>
/// Declaration for the updating the general settings callback function. /// Declaration for the updating the general settings callback function.
@@ -351,9 +351,9 @@ namespace Microsoft.PowerToys.Settings.UI.Views
OpenFlyoutCallback(p); OpenFlyoutCallback(p);
} }
else if (whatToShowJson.ValueType == JsonValueType.String && whatToShowJson.GetString().Equals("main_page", StringComparison.Ordinal)) else if (whatToShowJson.ValueType == JsonValueType.String)
{ {
OpenMainWindowCallback(); OpenMainWindowCallback(App.GetPage(whatToShowJson.GetString()));
} }
} }
} }