mirror of
https://github.com/microsoft/PowerToys.git
synced 2025-12-15 11:17:53 +01:00
push
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio Version 17
|
# Visual Studio Version 18
|
||||||
VisualStudioVersion = 17.0.32014.148
|
VisualStudioVersion = 18.3.11206.111
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runner", "src\runner\runner.vcxproj", "{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "runner", "src\runner\runner.vcxproj", "{9412D5C6-2CF2-4FC2-A601-B55508EA9B27}"
|
||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
@@ -374,8 +374,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "AlwaysOnTop", "AlwaysOnTop"
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AlwaysOnTop", "src\modules\alwaysontop\AlwaysOnTop\AlwaysOnTop.vcxproj", "{1DC3BE92-CE89-43FB-8110-9C043A2FE7A2}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AlwaysOnTop", "src\modules\alwaysontop\AlwaysOnTop\AlwaysOnTop.vcxproj", "{1DC3BE92-CE89-43FB-8110-9C043A2FE7A2}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "AlwaysOnTopModuleInterface", "src\modules\alwaysontop\AlwaysOnTopModuleInterface\AlwaysOnTopModuleInterface.vcxproj", "{48A0A19E-A0BE-4256-ACF8-CC3B80291AF9}"
|
|
||||||
EndProject
|
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Community.PowerToys.Run.Plugin.WebSearch", "src\modules\launcher\Plugins\Community.PowerToys.Run.Plugin.WebSearch\Community.PowerToys.Run.Plugin.WebSearch.csproj", "{9F94B303-5E21-4364-9362-64426F8DB932}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Community.PowerToys.Run.Plugin.WebSearch", "src\modules\launcher\Plugins\Community.PowerToys.Run.Plugin.WebSearch\Community.PowerToys.Run.Plugin.WebSearch.csproj", "{9F94B303-5E21-4364-9362-64426F8DB932}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MousePointerCrosshairs", "src\modules\MouseUtils\MousePointerCrosshairs\MousePointerCrosshairs.vcxproj", "{EAE14C0E-7A6B-45DA-9080-A7D8C077BA6E}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MousePointerCrosshairs", "src\modules\MouseUtils\MousePointerCrosshairs\MousePointerCrosshairs.vcxproj", "{EAE14C0E-7A6B-45DA-9080-A7D8C077BA6E}"
|
||||||
@@ -443,8 +441,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Hosts", "Hosts", "{F05E590D
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostsEditor.UnitTests", "src\modules\Hosts\Hosts.Tests\HostsEditor.UnitTests.csproj", "{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HostsEditor.UnitTests", "src\modules\Hosts\Hosts.Tests\HostsEditor.UnitTests.csproj", "{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "HostsModuleInterface", "src\modules\Hosts\HostsModuleInterface\HostsModuleInterface.vcxproj", "{B41B888C-7DB8-4747-B262-4062E05A230D}"
|
|
||||||
EndProject
|
|
||||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileLocksmith", "FileLocksmith", "{AB82E5DD-C32D-4F28-9746-2C780846188E}"
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "FileLocksmith", "FileLocksmith", "{AB82E5DD-C32D-4F28-9746-2C780846188E}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithExt", "src\modules\FileLocksmith\FileLocksmithExt\FileLocksmithExt.vcxproj", "{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}"
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FileLocksmithExt", "src\modules\FileLocksmith\FileLocksmithExt\FileLocksmithExt.vcxproj", "{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}"
|
||||||
@@ -834,6 +830,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LanguageModelProvider", "sr
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.UI.ViewModels.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.UI.ViewModels.UnitTests\Microsoft.CmdPal.UI.ViewModels.UnitTests.csproj", "{A66E9270-5D93-EC9C-F06E-CE7295BB9A6C}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.CmdPal.UI.ViewModels.UnitTests", "src\modules\cmdpal\Tests\Microsoft.CmdPal.UI.ViewModels.UnitTests\Microsoft.CmdPal.UI.ViewModels.UnitTests.csproj", "{A66E9270-5D93-EC9C-F06E-CE7295BB9A6C}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RunnerV2", "src\RunnerV2\RunnerV2\RunnerV2.csproj", "{20C43796-E14D-47B2-843A-843CAC9C0D28}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AlwaysOnTopModuleInterface", "src\modules\alwaysontop\AlwaysOnTopModuleInterface\AlwaysOnTopModuleInterface.csproj", "{2CF11A08-1A1F-4F75-BC41-F982FCF26D2F}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|ARM64 = Debug|ARM64
|
Debug|ARM64 = Debug|ARM64
|
||||||
@@ -1610,14 +1610,6 @@ Global
|
|||||||
{1DC3BE92-CE89-43FB-8110-9C043A2FE7A2}.Release|ARM64.Build.0 = Release|ARM64
|
{1DC3BE92-CE89-43FB-8110-9C043A2FE7A2}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{1DC3BE92-CE89-43FB-8110-9C043A2FE7A2}.Release|x64.ActiveCfg = Release|x64
|
{1DC3BE92-CE89-43FB-8110-9C043A2FE7A2}.Release|x64.ActiveCfg = Release|x64
|
||||||
{1DC3BE92-CE89-43FB-8110-9C043A2FE7A2}.Release|x64.Build.0 = Release|x64
|
{1DC3BE92-CE89-43FB-8110-9C043A2FE7A2}.Release|x64.Build.0 = Release|x64
|
||||||
{48A0A19E-A0BE-4256-ACF8-CC3B80291AF9}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
|
||||||
{48A0A19E-A0BE-4256-ACF8-CC3B80291AF9}.Debug|ARM64.Build.0 = Debug|ARM64
|
|
||||||
{48A0A19E-A0BE-4256-ACF8-CC3B80291AF9}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{48A0A19E-A0BE-4256-ACF8-CC3B80291AF9}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{48A0A19E-A0BE-4256-ACF8-CC3B80291AF9}.Release|ARM64.ActiveCfg = Release|ARM64
|
|
||||||
{48A0A19E-A0BE-4256-ACF8-CC3B80291AF9}.Release|ARM64.Build.0 = Release|ARM64
|
|
||||||
{48A0A19E-A0BE-4256-ACF8-CC3B80291AF9}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{48A0A19E-A0BE-4256-ACF8-CC3B80291AF9}.Release|x64.Build.0 = Release|x64
|
|
||||||
{9F94B303-5E21-4364-9362-64426F8DB932}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
{9F94B303-5E21-4364-9362-64426F8DB932}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
{9F94B303-5E21-4364-9362-64426F8DB932}.Debug|ARM64.Build.0 = Debug|ARM64
|
{9F94B303-5E21-4364-9362-64426F8DB932}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
{9F94B303-5E21-4364-9362-64426F8DB932}.Debug|x64.ActiveCfg = Debug|x64
|
{9F94B303-5E21-4364-9362-64426F8DB932}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
@@ -1826,14 +1818,6 @@ Global
|
|||||||
{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A}.Release|ARM64.Build.0 = Release|ARM64
|
{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A}.Release|x64.ActiveCfg = Release|x64
|
{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A}.Release|x64.ActiveCfg = Release|x64
|
||||||
{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A}.Release|x64.Build.0 = Release|x64
|
{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A}.Release|x64.Build.0 = Release|x64
|
||||||
{B41B888C-7DB8-4747-B262-4062E05A230D}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
|
||||||
{B41B888C-7DB8-4747-B262-4062E05A230D}.Debug|ARM64.Build.0 = Debug|ARM64
|
|
||||||
{B41B888C-7DB8-4747-B262-4062E05A230D}.Debug|x64.ActiveCfg = Debug|x64
|
|
||||||
{B41B888C-7DB8-4747-B262-4062E05A230D}.Debug|x64.Build.0 = Debug|x64
|
|
||||||
{B41B888C-7DB8-4747-B262-4062E05A230D}.Release|ARM64.ActiveCfg = Release|ARM64
|
|
||||||
{B41B888C-7DB8-4747-B262-4062E05A230D}.Release|ARM64.Build.0 = Release|ARM64
|
|
||||||
{B41B888C-7DB8-4747-B262-4062E05A230D}.Release|x64.ActiveCfg = Release|x64
|
|
||||||
{B41B888C-7DB8-4747-B262-4062E05A230D}.Release|x64.Build.0 = Release|x64
|
|
||||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|ARM64.Build.0 = Debug|ARM64
|
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|x64.ActiveCfg = Debug|x64
|
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
@@ -3036,6 +3020,22 @@ Global
|
|||||||
{A66E9270-5D93-EC9C-F06E-CE7295BB9A6C}.Release|ARM64.Build.0 = Release|ARM64
|
{A66E9270-5D93-EC9C-F06E-CE7295BB9A6C}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
{A66E9270-5D93-EC9C-F06E-CE7295BB9A6C}.Release|x64.ActiveCfg = Release|x64
|
{A66E9270-5D93-EC9C-F06E-CE7295BB9A6C}.Release|x64.ActiveCfg = Release|x64
|
||||||
{A66E9270-5D93-EC9C-F06E-CE7295BB9A6C}.Release|x64.Build.0 = Release|x64
|
{A66E9270-5D93-EC9C-F06E-CE7295BB9A6C}.Release|x64.Build.0 = Release|x64
|
||||||
|
{20C43796-E14D-47B2-843A-843CAC9C0D28}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{20C43796-E14D-47B2-843A-843CAC9C0D28}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{20C43796-E14D-47B2-843A-843CAC9C0D28}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{20C43796-E14D-47B2-843A-843CAC9C0D28}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{20C43796-E14D-47B2-843A-843CAC9C0D28}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{20C43796-E14D-47B2-843A-843CAC9C0D28}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{20C43796-E14D-47B2-843A-843CAC9C0D28}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{20C43796-E14D-47B2-843A-843CAC9C0D28}.Release|x64.Build.0 = Release|x64
|
||||||
|
{2CF11A08-1A1F-4F75-BC41-F982FCF26D2F}.Debug|ARM64.ActiveCfg = Debug|ARM64
|
||||||
|
{2CF11A08-1A1F-4F75-BC41-F982FCF26D2F}.Debug|ARM64.Build.0 = Debug|ARM64
|
||||||
|
{2CF11A08-1A1F-4F75-BC41-F982FCF26D2F}.Debug|x64.ActiveCfg = Debug|x64
|
||||||
|
{2CF11A08-1A1F-4F75-BC41-F982FCF26D2F}.Debug|x64.Build.0 = Debug|x64
|
||||||
|
{2CF11A08-1A1F-4F75-BC41-F982FCF26D2F}.Release|ARM64.ActiveCfg = Release|ARM64
|
||||||
|
{2CF11A08-1A1F-4F75-BC41-F982FCF26D2F}.Release|ARM64.Build.0 = Release|ARM64
|
||||||
|
{2CF11A08-1A1F-4F75-BC41-F982FCF26D2F}.Release|x64.ActiveCfg = Release|x64
|
||||||
|
{2CF11A08-1A1F-4F75-BC41-F982FCF26D2F}.Release|x64.Build.0 = Release|x64
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
@@ -3150,7 +3150,6 @@ Global
|
|||||||
{FCF3E52D-B80A-4FC3-98FD-6391354F0EE3} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
{FCF3E52D-B80A-4FC3-98FD-6391354F0EE3} = {6B01F1CF-F4DB-48B5-BFE7-0BF576C1D704}
|
||||||
{60CD2D4F-C3B9-4897-9821-FCA5098B41CE} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
{60CD2D4F-C3B9-4897-9821-FCA5098B41CE} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||||
{1DC3BE92-CE89-43FB-8110-9C043A2FE7A2} = {60CD2D4F-C3B9-4897-9821-FCA5098B41CE}
|
{1DC3BE92-CE89-43FB-8110-9C043A2FE7A2} = {60CD2D4F-C3B9-4897-9821-FCA5098B41CE}
|
||||||
{48A0A19E-A0BE-4256-ACF8-CC3B80291AF9} = {60CD2D4F-C3B9-4897-9821-FCA5098B41CE}
|
|
||||||
{9F94B303-5E21-4364-9362-64426F8DB932} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
{9F94B303-5E21-4364-9362-64426F8DB932} = {4AFC9975-2456-4C70-94A4-84073C1CED93}
|
||||||
{EAE14C0E-7A6B-45DA-9080-A7D8C077BA6E} = {322566EF-20DC-43A6-B9F8-616AF942579A}
|
{EAE14C0E-7A6B-45DA-9080-A7D8C077BA6E} = {322566EF-20DC-43A6-B9F8-616AF942579A}
|
||||||
{F7C8C0F1-5431-4347-89D0-8E5354F93CF2} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
{F7C8C0F1-5431-4347-89D0-8E5354F93CF2} = {2F305555-C296-497E-AC20-5FA1B237996A}
|
||||||
@@ -3182,7 +3181,6 @@ Global
|
|||||||
{31D1C81D-765F-4446-AA62-E743F6325049} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
{31D1C81D-765F-4446-AA62-E743F6325049} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
||||||
{F05E590D-AD46-42BE-9C25-6A63ADD2E3EA} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
{F05E590D-AD46-42BE-9C25-6A63ADD2E3EA} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||||
{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A} = {1C48CD47-D610-463A-A53C-AF82DD6C47E7}
|
{E2D03E0F-7A75-4813-9F4B-D8763D43FD3A} = {1C48CD47-D610-463A-A53C-AF82DD6C47E7}
|
||||||
{B41B888C-7DB8-4747-B262-4062E05A230D} = {F05E590D-AD46-42BE-9C25-6A63ADD2E3EA}
|
|
||||||
{AB82E5DD-C32D-4F28-9746-2C780846188E} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
{AB82E5DD-C32D-4F28-9746-2C780846188E} = {4574FDD0-F61D-4376-98BF-E5A1262C11EC}
|
||||||
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
{57175EC7-92A5-4C1E-8244-E3FBCA2A81DE} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
||||||
{E69B044A-2F8A-45AA-AD0B-256C59421807} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
{E69B044A-2F8A-45AA-AD0B-256C59421807} = {AB82E5DD-C32D-4F28-9746-2C780846188E}
|
||||||
@@ -3367,6 +3365,7 @@ Global
|
|||||||
{4E0FCF69-B06B-D272-76BF-ED3A559B4EDA} = {8EF25507-2575-4ADE-BF7E-D23376903AB8}
|
{4E0FCF69-B06B-D272-76BF-ED3A559B4EDA} = {8EF25507-2575-4ADE-BF7E-D23376903AB8}
|
||||||
{45354F4F-1414-45CE-B600-51CD1209FD19} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
{45354F4F-1414-45CE-B600-51CD1209FD19} = {1AFB6476-670D-4E80-A464-657E01DFF482}
|
||||||
{A66E9270-5D93-EC9C-F06E-CE7295BB9A6C} = {8EF25507-2575-4ADE-BF7E-D23376903AB8}
|
{A66E9270-5D93-EC9C-F06E-CE7295BB9A6C} = {8EF25507-2575-4ADE-BF7E-D23376903AB8}
|
||||||
|
{2CF11A08-1A1F-4F75-BC41-F982FCF26D2F} = {60CD2D4F-C3B9-4897-9821-FCA5098B41CE}
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
SolutionGuid = {C3A2F9D1-7930-4EF4-A6FC-7EE0A99821D0}
|
||||||
|
|||||||
42
src/RunnerV2/RunnerV2/Helpers/ElevationHelper.cs
Normal file
42
src/RunnerV2/RunnerV2/Helpers/ElevationHelper.cs
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
// 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.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using static RunnerV2.NativeMethods;
|
||||||
|
|
||||||
|
namespace RunnerV2.Helpers
|
||||||
|
{
|
||||||
|
internal static partial class ElevationHelper
|
||||||
|
{
|
||||||
|
private static bool? _cachedValue;
|
||||||
|
|
||||||
|
internal static bool IsProcessElevated(bool useCachedValue = true)
|
||||||
|
{
|
||||||
|
if (_cachedValue is not null && useCachedValue)
|
||||||
|
{
|
||||||
|
return _cachedValue.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool elevated = false;
|
||||||
|
if (OpenProcessToken(Process.GetCurrentProcess().Handle, TOKENQUERY, out nint token))
|
||||||
|
{
|
||||||
|
TokenElevation elevation = default;
|
||||||
|
if (GetTokenInformation(token, TOKEN_INFORMATION_CLASS.TOKEN_ELEVATION, ref elevation, (uint)Marshal.SizeOf(elevation), out uint _))
|
||||||
|
{
|
||||||
|
elevated = elevation.TokenIsElevated != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
CloseHandle(token);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_cachedValue = elevated;
|
||||||
|
return elevated;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
55
src/RunnerV2/RunnerV2/Helpers/HotkeyManager.cs
Normal file
55
src/RunnerV2/RunnerV2/Helpers/HotkeyManager.cs
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
// 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 System.Runtime.InteropServices;
|
||||||
|
using ManagedCommon;
|
||||||
|
using static RunnerV2.NativeMethods;
|
||||||
|
|
||||||
|
namespace RunnerV2.Helpers
|
||||||
|
{
|
||||||
|
internal static partial class HotkeyManager
|
||||||
|
{
|
||||||
|
private static readonly Dictionary<HotkeyEx, Action> _hotkeyActions = [];
|
||||||
|
|
||||||
|
public static void EnableHotkey(HotkeyEx hotkey, Action onHotkey)
|
||||||
|
{
|
||||||
|
if (_hotkeyActions.ContainsKey(hotkey))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_hotkeyActions[hotkey] = onHotkey;
|
||||||
|
|
||||||
|
if (!RegisterHotKey(Runner.RunnerHwnd, hotkey.GetHashCode(), hotkey.ModifiersMask, hotkey.VkCode))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Failed to register hotkey: " + hotkey);
|
||||||
|
var lastError = Marshal.GetLastWin32Error();
|
||||||
|
Console.WriteLine("LastError: " + lastError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DisableHotkey(HotkeyEx hotkey)
|
||||||
|
{
|
||||||
|
if (!_hotkeyActions.ContainsKey(hotkey))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_hotkeyActions.Remove(hotkey);
|
||||||
|
UnregisterHotKey(IntPtr.Zero, hotkey.GetHashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ProcessHotkey(nuint hotkeyId)
|
||||||
|
{
|
||||||
|
ulong hashId = hotkeyId.ToUInt64();
|
||||||
|
if (_hotkeyActions.Any(h => h.Key.GetHashCode() == (int)hashId))
|
||||||
|
{
|
||||||
|
_hotkeyActions.First(h => h.Key.GetHashCode() == (int)hashId).Value();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
148
src/RunnerV2/RunnerV2/Helpers/SettingsHelper.cs
Normal file
148
src/RunnerV2/RunnerV2/Helpers/SettingsHelper.cs
Normal 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.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Pipelines;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text.Json;
|
||||||
|
using ManagedCommon;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Library;
|
||||||
|
using PowerToys.Interop;
|
||||||
|
|
||||||
|
namespace RunnerV2.Helpers
|
||||||
|
{
|
||||||
|
internal static class SettingsHelper
|
||||||
|
{
|
||||||
|
private static Process? _process;
|
||||||
|
private static TwoWayPipeMessageIPCManaged? _ipc;
|
||||||
|
private static SettingsUtils _settingsUtils = new();
|
||||||
|
|
||||||
|
public static void OpenSettingsWindow(bool showOobeWindow = false, bool showScoobeWindow = false, bool showFlyout = false, Point? flyoutPosition = null, string? additionalArguments = null)
|
||||||
|
{
|
||||||
|
if (_process is not null && _ipc is not null && !_process.HasExited)
|
||||||
|
{
|
||||||
|
if (showFlyout)
|
||||||
|
{
|
||||||
|
_ipc.Send(@"{""ShowYourself"": ""flyout""}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_ipc.Send($@"{{""ShowYourself"": ""{additionalArguments ?? "Dashboard"}""}}");
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_ipc?.End();
|
||||||
|
_ipc = null;
|
||||||
|
|
||||||
|
// Arg 1: Executable path
|
||||||
|
string executablePath = Path.Combine(Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location) ?? throw new InvalidOperationException("No executable path found"), "WinUI3Apps", "PowerToys.Settings.exe");
|
||||||
|
|
||||||
|
// Arg 2,3: Pipe names
|
||||||
|
Pipe settingsPipe = new();
|
||||||
|
Pipe powertoysPipe = new();
|
||||||
|
|
||||||
|
string powerToysPipeName = @"\\.\pipe\powertoys_runner_" + Guid.NewGuid();
|
||||||
|
string settingsPipeName = @"\\.\pipe\powertoys_settings_" + Guid.NewGuid();
|
||||||
|
|
||||||
|
// Arg 4: Process pid
|
||||||
|
string currentProcessId = Environment.ProcessId.ToString(CultureInfo.InvariantCulture);
|
||||||
|
|
||||||
|
// Arg 5: Settings theme
|
||||||
|
string theme = Program.GeneralSettings.Theme switch
|
||||||
|
{
|
||||||
|
"light" => "light",
|
||||||
|
"dark" => "dark",
|
||||||
|
"system" when ThemeHelpers.GetAppTheme() == AppTheme.Light => "light",
|
||||||
|
"system" when ThemeHelpers.GetAppTheme() == AppTheme.Dark => "dark",
|
||||||
|
_ => throw new NotImplementedException(),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Arg 6: Elevated status
|
||||||
|
string isElevated = Program.GeneralSettings.IsElevated ? "true" : "false";
|
||||||
|
|
||||||
|
// Arg 7: Is user an administrator
|
||||||
|
string isAdmin = Program.GeneralSettings.IsAdmin ? "true" : "false";
|
||||||
|
|
||||||
|
// Arg 8: Show OOBE window
|
||||||
|
string showOobeArg = showOobeWindow ? "true" : "false";
|
||||||
|
|
||||||
|
// Arg 9: Show SCOOBE window
|
||||||
|
string showScoobeArg = showScoobeWindow ? "true" : "false";
|
||||||
|
|
||||||
|
// Arg 10: Show flyout
|
||||||
|
string showFlyoutArg = showFlyout ? "true" : "false";
|
||||||
|
|
||||||
|
// Arg 11: Are there additional settings window arguments
|
||||||
|
string areThereadditionalArgs = string.IsNullOrEmpty(additionalArguments) ? "false" : "true";
|
||||||
|
|
||||||
|
// Arg 12: Are there flyout position arguments
|
||||||
|
string areThereFlyoutPositionArgs = flyoutPosition.HasValue ? "true" : "false";
|
||||||
|
|
||||||
|
string executableArgs = $"{powerToysPipeName} {settingsPipeName} {currentProcessId} {theme} {isElevated} {isAdmin} {showOobeArg} {showScoobeArg} {showFlyoutArg} {areThereadditionalArgs} {areThereFlyoutPositionArgs}";
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(additionalArguments))
|
||||||
|
{
|
||||||
|
executableArgs += $" {additionalArguments}";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (flyoutPosition is not null)
|
||||||
|
{
|
||||||
|
executableArgs += $" {flyoutPosition.Value.X} {flyoutPosition.Value.Y}";
|
||||||
|
}
|
||||||
|
|
||||||
|
_process = Process.Start(executablePath, executableArgs);
|
||||||
|
|
||||||
|
// Initialize listening to pipes
|
||||||
|
_ipc = new TwoWayPipeMessageIPCManaged(powerToysPipeName, settingsPipeName, OnSettingsMessageReceived);
|
||||||
|
_ipc.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnSettingsMessageReceived(string message)
|
||||||
|
{
|
||||||
|
JsonDocument messageDocument = JsonDocument.Parse(message);
|
||||||
|
|
||||||
|
foreach (var property in messageDocument.RootElement.EnumerateObject())
|
||||||
|
{
|
||||||
|
switch (property.Name)
|
||||||
|
{
|
||||||
|
case "get_all_hotkey_conflicts":
|
||||||
|
// Todo: Handle hotkey conflict
|
||||||
|
break;
|
||||||
|
case "general":
|
||||||
|
_settingsUtils.SaveSettings(property.Value.ToString(), string.Empty);
|
||||||
|
foreach (IPowerToysModule module in Runner.LoadedModules)
|
||||||
|
{
|
||||||
|
module.OnSettingsChanged("general", property.Value);
|
||||||
|
Runner.ToggleModuleStateBasedOnEnabledProperty(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
case string s:
|
||||||
|
_settingsUtils.SaveSettings(property.Value.ToString(), s);
|
||||||
|
|
||||||
|
if (Runner.LoadedModules.Find(m => m.Name == s) is IPowerToysModule moduleFound)
|
||||||
|
{
|
||||||
|
moduleFound.OnSettingsChanged(s, property.Value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If no specific module was found, notify all enabled modules
|
||||||
|
foreach (IPowerToysModule module in Runner.LoadedModules.Where(m => m.Enabled))
|
||||||
|
{
|
||||||
|
module.OnSettingsChanged(s, property.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
134
src/RunnerV2/RunnerV2/Helpers/TrayIconManager.cs
Normal file
134
src/RunnerV2/RunnerV2/Helpers/TrayIconManager.cs
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
// 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.Diagnostics;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using static RunnerV2.NativeMethods;
|
||||||
|
|
||||||
|
namespace RunnerV2.Helpers
|
||||||
|
{
|
||||||
|
internal static partial class TrayIconManager
|
||||||
|
{
|
||||||
|
internal static void StartTrayIcon()
|
||||||
|
{
|
||||||
|
NOTIFYICONDATA notifyicondata = new()
|
||||||
|
{
|
||||||
|
CbSize = (uint)Marshal.SizeOf<NOTIFYICONDATA>(),
|
||||||
|
HWnd = Runner.RunnerHwnd,
|
||||||
|
UId = 1,
|
||||||
|
HIcon = Icon.ExtractAssociatedIcon(Environment.ProcessPath!)!.Handle,
|
||||||
|
UFlags = 0x0000001 | 0x00000002 | 0x4,
|
||||||
|
UCallbackMessage = (uint)WindowMessages.ICON_NOTIFY,
|
||||||
|
SzTip = "PowerToys Runner",
|
||||||
|
};
|
||||||
|
|
||||||
|
ChangeWindowMessageFilterEx(Runner.RunnerHwnd, 0x0111, 0x0001, IntPtr.Zero);
|
||||||
|
|
||||||
|
Shell_NotifyIcon(NIMADD, ref notifyicondata);
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum TrayButton : uint
|
||||||
|
{
|
||||||
|
Settings = 1,
|
||||||
|
Documentation,
|
||||||
|
ReportBug,
|
||||||
|
Close,
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool _doubleClickTimerRunning;
|
||||||
|
private static bool _doubleClickDetected;
|
||||||
|
|
||||||
|
private static IntPtr _trayIconMenu;
|
||||||
|
|
||||||
|
static TrayIconManager()
|
||||||
|
{
|
||||||
|
_trayIconMenu = CreatePopupMenu();
|
||||||
|
AppendMenuW(_trayIconMenu, 0u, new UIntPtr((uint)TrayButton.Settings), "Settings\tDouble-click");
|
||||||
|
AppendMenuW(_trayIconMenu, 0x00000800u, UIntPtr.Zero, string.Empty); // separator
|
||||||
|
AppendMenuW(_trayIconMenu, 0u, new UIntPtr((uint)TrayButton.Documentation), "Documentation");
|
||||||
|
AppendMenuW(_trayIconMenu, 0u, new UIntPtr((uint)TrayButton.ReportBug), "Report a Bug");
|
||||||
|
AppendMenuW(_trayIconMenu, 0x00000800u, UIntPtr.Zero, string.Empty); // separator
|
||||||
|
AppendMenuW(_trayIconMenu, 0u, new UIntPtr((uint)TrayButton.Close), "Close");
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void ProcessTrayIconMessage(long lParam)
|
||||||
|
{
|
||||||
|
switch (lParam)
|
||||||
|
{
|
||||||
|
case 0x0205: // WM_RBUTTONDBLCLK
|
||||||
|
case 0x007B: // WM_CONTEXTMENU
|
||||||
|
SetForegroundWindow(Runner.RunnerHwnd);
|
||||||
|
TrackPopupMenu(_trayIconMenu, 0x0004 | 0x0020, Cursor.Position.X, Cursor.Position.Y, 0, Runner.RunnerHwnd, IntPtr.Zero);
|
||||||
|
break;
|
||||||
|
case 0x0202: // WM_LBUTTONUP
|
||||||
|
if (_doubleClickTimerRunning)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_doubleClickTimerRunning = true;
|
||||||
|
Task.Delay(SystemInformation.DoubleClickTime).ContinueWith(_ =>
|
||||||
|
{
|
||||||
|
if (!_doubleClickDetected)
|
||||||
|
{
|
||||||
|
SettingsHelper.OpenSettingsWindow(showFlyout: true, flyoutPosition: Cursor.Position);
|
||||||
|
}
|
||||||
|
|
||||||
|
_doubleClickDetected = false;
|
||||||
|
_doubleClickTimerRunning = false;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 0x0203: // WM_LBUTTONDBLCLK
|
||||||
|
_doubleClickDetected = true;
|
||||||
|
SettingsHelper.OpenSettingsWindow();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static void ProcessTrayMenuCommand(nuint commandId)
|
||||||
|
{
|
||||||
|
switch ((TrayButton)commandId)
|
||||||
|
{
|
||||||
|
case TrayButton.Settings:
|
||||||
|
SettingsHelper.OpenSettingsWindow();
|
||||||
|
break;
|
||||||
|
case TrayButton.Documentation:
|
||||||
|
Process.Start(new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = "https://aka.ms/PowerToysOverview",
|
||||||
|
UseShellExecute = true,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case TrayButton.ReportBug:
|
||||||
|
Process bugReportProcess = new();
|
||||||
|
bugReportProcess.StartInfo = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = "Tools\\PowerToys.BugReportTool.exe",
|
||||||
|
CreateNoWindow = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
bugReportProcess.EnableRaisingEvents = true;
|
||||||
|
|
||||||
|
EnableMenuItem(_trayIconMenu, (uint)TrayButton.ReportBug, 0x000000 | 0x00001);
|
||||||
|
|
||||||
|
bugReportProcess.Exited += (sender, e) =>
|
||||||
|
{
|
||||||
|
bugReportProcess.Dispose();
|
||||||
|
EnableMenuItem(_trayIconMenu, (uint)TrayButton.ReportBug, 0x00000000);
|
||||||
|
};
|
||||||
|
|
||||||
|
bugReportProcess.Start();
|
||||||
|
|
||||||
|
break;
|
||||||
|
case TrayButton.Close:
|
||||||
|
Runner.Close();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
14
src/RunnerV2/RunnerV2/Models/SpecialMode.cs
Normal file
14
src/RunnerV2/RunnerV2/Models/SpecialMode.cs
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
// 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 RunnerV2.Models
|
||||||
|
{
|
||||||
|
internal enum SpecialMode
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
Win32ToastNotificationCOMServer,
|
||||||
|
ToastNotificationHandler,
|
||||||
|
ReportSuccessfulUpdate,
|
||||||
|
}
|
||||||
|
}
|
||||||
176
src/RunnerV2/RunnerV2/NativeMethods.cs
Normal file
176
src/RunnerV2/RunnerV2/NativeMethods.cs
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
// 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.Drawing;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
namespace RunnerV2
|
||||||
|
{
|
||||||
|
internal static partial class NativeMethods
|
||||||
|
{
|
||||||
|
[LibraryImport("advapi32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static partial bool OpenProcessToken(IntPtr processHandle, uint desiredAccess, out IntPtr tokenHandle);
|
||||||
|
|
||||||
|
[LibraryImport("advapi32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static partial bool GetTokenInformation(IntPtr tokenHandle, TOKEN_INFORMATION_CLASS tokenInformationClass, ref TokenElevation tokenInformation, uint tokenInformationLength, out uint returnLength);
|
||||||
|
|
||||||
|
[LibraryImport("Kernel32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static partial bool CloseHandle(IntPtr hObject);
|
||||||
|
|
||||||
|
internal enum TOKEN_INFORMATION_CLASS
|
||||||
|
{
|
||||||
|
TOKEN_ELEVATION = 20,
|
||||||
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct TokenElevation
|
||||||
|
{
|
||||||
|
public uint TokenIsElevated;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal const int TOKENQUERY = 0x0008;
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static partial bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static partial bool UnregisterHotKey(IntPtr hWnd, int id);
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static partial bool AppendMenuW(IntPtr hMenu, uint uFlags, UIntPtr uIDNewItem, string lpNewItem);
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll", SetLastError = true)]
|
||||||
|
internal static partial IntPtr CreatePopupMenu();
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static partial bool SetForegroundWindow(IntPtr hWnd);
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static partial bool TrackPopupMenu(IntPtr hMenu, uint uFlags, int x, int y, int nReserved, IntPtr hWnd, IntPtr prcRect);
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static partial bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable);
|
||||||
|
|
||||||
|
internal const uint NIMADD = 0x00000000;
|
||||||
|
|
||||||
|
internal struct NOTIFYICONDATA
|
||||||
|
{
|
||||||
|
public uint CbSize;
|
||||||
|
public IntPtr HWnd;
|
||||||
|
public uint UId;
|
||||||
|
public uint UFlags;
|
||||||
|
public uint UCallbackMessage;
|
||||||
|
public IntPtr HIcon;
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 128)]
|
||||||
|
public string SzTip;
|
||||||
|
public uint DwState;
|
||||||
|
public uint DwStateMask;
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
|
||||||
|
public string SzInfo;
|
||||||
|
public uint UTimeoutOrVersion;
|
||||||
|
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]
|
||||||
|
public string SzInfoTitle;
|
||||||
|
public uint DwInfoFlags;
|
||||||
|
public Guid GuidItem;
|
||||||
|
public IntPtr HBalloonIcon;
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("shell32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static extern bool Shell_NotifyIcon(uint dwMessage, ref NOTIFYICONDATA lpdata);
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll", SetLastError = true)]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static partial bool ChangeWindowMessageFilterEx(IntPtr hWnd, uint msg, uint action, IntPtr pChangeFilterStruct);
|
||||||
|
|
||||||
|
internal const uint CSVREDRAW = 0x0001;
|
||||||
|
internal const uint CSHREDRAW = 0x0002;
|
||||||
|
|
||||||
|
internal const uint WSOVERLAPPEDWINDOW = 0x00CF0000;
|
||||||
|
internal const uint WSPOPUP = 0x80000000;
|
||||||
|
|
||||||
|
internal const int CWUSEDEFAULT = unchecked((int)0x80000000);
|
||||||
|
|
||||||
|
internal static readonly IntPtr IDCARROW = new(32512);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
internal static extern IntPtr GetMessageW(out MSG lpMsg, IntPtr hWnd, uint wMsgFilterMin, uint wMsgFilterMax);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static extern bool TranslateMessage(ref MSG lpMsg);
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
[return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
internal static extern bool DispatchMessageW(ref MSG lpMsg);
|
||||||
|
|
||||||
|
internal struct MSG
|
||||||
|
{
|
||||||
|
public IntPtr HWnd;
|
||||||
|
public uint Message;
|
||||||
|
public UIntPtr WParam;
|
||||||
|
public long LParam;
|
||||||
|
public ulong Time;
|
||||||
|
public Point Pt;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal enum WindowMessages : uint
|
||||||
|
{
|
||||||
|
COMMAND = 0x0111,
|
||||||
|
HOTKEY = 0x0312,
|
||||||
|
ICON_NOTIFY = 0x0800,
|
||||||
|
}
|
||||||
|
|
||||||
|
[DllImport("user32.dll")]
|
||||||
|
internal static extern ushort RegisterClassW(ref WNDCLASS lpWndClass);
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll", SetLastError = false)]
|
||||||
|
internal static partial IntPtr DefWindowProcW(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||||
|
|
||||||
|
[LibraryImport("user32.dll", SetLastError = true, StringMarshalling = StringMarshalling.Utf16)]
|
||||||
|
internal static partial nint CreateWindowExW(
|
||||||
|
uint dwExStyle,
|
||||||
|
string lpClassName,
|
||||||
|
string lpWindowName,
|
||||||
|
uint dwStyle,
|
||||||
|
int x,
|
||||||
|
int y,
|
||||||
|
int nWidth,
|
||||||
|
int nHeight,
|
||||||
|
IntPtr hWndParent,
|
||||||
|
IntPtr hMenu,
|
||||||
|
IntPtr hInstance,
|
||||||
|
IntPtr lpParam);
|
||||||
|
|
||||||
|
[UnmanagedFunctionPointer(CallingConvention.Winapi)]
|
||||||
|
internal delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
|
||||||
|
internal struct WNDCLASS
|
||||||
|
{
|
||||||
|
public uint Style;
|
||||||
|
public WndProc LpfnWndProc;
|
||||||
|
public int CbClsExtra;
|
||||||
|
public int CbWndExtra;
|
||||||
|
public IntPtr HInstance;
|
||||||
|
public IntPtr HIcon;
|
||||||
|
public IntPtr HCursor;
|
||||||
|
public IntPtr HbrBackground;
|
||||||
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
|
public string LpszMenuName;
|
||||||
|
[MarshalAs(UnmanagedType.LPWStr)]
|
||||||
|
public string LpszClassName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
98
src/RunnerV2/RunnerV2/Program.cs
Normal file
98
src/RunnerV2/RunnerV2/Program.cs
Normal file
@@ -0,0 +1,98 @@
|
|||||||
|
// 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.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Library;
|
||||||
|
using PowerToys.GPOWrapperProjection;
|
||||||
|
using RunnerV2;
|
||||||
|
using RunnerV2.Helpers;
|
||||||
|
using RunnerV2.Models;
|
||||||
|
using Settings.UI.Library;
|
||||||
|
|
||||||
|
internal sealed class Program
|
||||||
|
{
|
||||||
|
private static readonly SettingsUtils _settingsUtils = new();
|
||||||
|
private static GeneralSettings _generalSettings = _settingsUtils.GetSettings<GeneralSettings>();
|
||||||
|
|
||||||
|
public static GeneralSettings GeneralSettings => _generalSettings;
|
||||||
|
|
||||||
|
private static void Main(string[] args)
|
||||||
|
{
|
||||||
|
switch (ShouldRunInSpecialMode(args))
|
||||||
|
{
|
||||||
|
case SpecialMode.None:
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new NotImplementedException("Special modes are not implemented yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool shouldOpenSettings = args.Any(s => s.StartsWith("--open-settings", StringComparison.InvariantCulture));
|
||||||
|
bool shouldOpenSettingsToSpecificPage = args.Any(s => s.StartsWith("--open-settings=", StringComparison.InvariantCulture));
|
||||||
|
|
||||||
|
// Check if PowerToys is already running
|
||||||
|
if (Process.GetProcessesByName(Process.GetCurrentProcess().ProcessName).Length > 1)
|
||||||
|
{
|
||||||
|
throw new NotImplementedException("Opening another instance window is not supported yet.");
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Todo: Data diagnotics
|
||||||
|
*/
|
||||||
|
|
||||||
|
bool isElevated = ElevationHelper.IsProcessElevated();
|
||||||
|
bool hasDontElevateArgument = args.Contains("--dont-elevate");
|
||||||
|
bool runElevatedSetting = _generalSettings.RunElevated;
|
||||||
|
bool hasRestartedElevatedArgment = args.Contains("--restartedElevated");
|
||||||
|
|
||||||
|
Action afterInitializationAction = () => { };
|
||||||
|
Version version = Assembly.GetExecutingAssembly().GetName().Version!;
|
||||||
|
|
||||||
|
if ($"v{version.Major}.{version.Minor}.{version.Build}" != _settingsUtils.GetSettings<LastVersionRunSettings>(fileName: "last_version_run.json").LastVersion && (!_generalSettings.ShowWhatsNewAfterUpdates || GPOWrapper.GetDisableShowWhatsNewAfterUpdatesValue() != GpoRuleConfigured.Disabled))
|
||||||
|
{
|
||||||
|
afterInitializationAction += () =>
|
||||||
|
{
|
||||||
|
SettingsHelper.OpenSettingsWindow(showScoobeWindow: true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_settingsUtils.GetSettings<OOBESettings>(fileName: "oobe_settings.json").OpenedAtFirstLaunch)
|
||||||
|
{
|
||||||
|
afterInitializationAction += () =>
|
||||||
|
{
|
||||||
|
SettingsHelper.OpenSettingsWindow(showOobeWindow: true);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set last version run
|
||||||
|
_settingsUtils.SaveSettings(new LastVersionRunSettings() { LastVersion = $"v{version.Major}.{version.Minor}.{version.Build}" }.ToJsonString(), fileName: "last_version_run.json");
|
||||||
|
|
||||||
|
switch ((isElevated, hasDontElevateArgument, runElevatedSetting, hasRestartedElevatedArgment))
|
||||||
|
{
|
||||||
|
case (true, true, false, _):
|
||||||
|
// Todo: Scheudle restart as non elevated
|
||||||
|
throw new NotImplementedException();
|
||||||
|
case (true, _, _, _):
|
||||||
|
case (_, _, false, _):
|
||||||
|
case (_, true, _, _):
|
||||||
|
case (false, _, _, true):
|
||||||
|
_ = Runner.Run(afterInitializationAction);
|
||||||
|
|
||||||
|
// Todo: Save settings
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// Todo: scheudle restart as elevated
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SpecialMode ShouldRunInSpecialMode(string[] args)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
return SpecialMode.None;
|
||||||
|
}
|
||||||
|
}
|
||||||
212
src/RunnerV2/RunnerV2/Runner.cs
Normal file
212
src/RunnerV2/RunnerV2/Runner.cs
Normal file
@@ -0,0 +1,212 @@
|
|||||||
|
// 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.Frozen;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using ManagedCommon;
|
||||||
|
using RunnerV2.Helpers;
|
||||||
|
using static RunnerV2.NativeMethods;
|
||||||
|
|
||||||
|
namespace RunnerV2
|
||||||
|
{
|
||||||
|
internal static partial class Runner
|
||||||
|
{
|
||||||
|
public static nint RunnerHwnd { get; private set; }
|
||||||
|
|
||||||
|
private const string TrayWindowClassName = "pt_tray_icon_window_class";
|
||||||
|
|
||||||
|
static Runner()
|
||||||
|
{
|
||||||
|
InitializeTrayWindow();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static List<IPowerToysModule> _successfullyAddedModules = [];
|
||||||
|
|
||||||
|
public static List<IPowerToysModule> LoadedModules => _successfullyAddedModules;
|
||||||
|
|
||||||
|
internal static bool Run(Action afterInitializationAction)
|
||||||
|
{
|
||||||
|
// Todo: Start tray icon
|
||||||
|
TrayIconManager.StartTrayIcon();
|
||||||
|
FrozenSet<string> modulesToLoad = ["PowerToys.AlwaysOnTopModuleInterface.dll", "WinUI3Apps\\PowerToys.Hosts.dll"];
|
||||||
|
|
||||||
|
List<string> failedModuleLoads = [];
|
||||||
|
|
||||||
|
foreach (string module in modulesToLoad)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Assembly moduleAssembly = Assembly.LoadFrom(Path.GetFullPath(module));
|
||||||
|
Type moduleInterfaceType = moduleAssembly.GetTypes().First(t => t.GetInterfaces().Any(i => i.Name.StartsWith(typeof(IPowerToysModule).Name, StringComparison.InvariantCulture)));
|
||||||
|
_successfullyAddedModules.Add((IPowerToysModule)Activator.CreateInstance(moduleInterfaceType)!);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
failedModuleLoads.Add(module);
|
||||||
|
Console.WriteLine($"Failed to load module {module}: {e.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failedModuleLoads.Count > 0)
|
||||||
|
{
|
||||||
|
MessageBox.Show("The following modules failed to load: \n- " + string.Join("\n- ", failedModuleLoads), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (IPowerToysModule module in _successfullyAddedModules)
|
||||||
|
{
|
||||||
|
ToggleModuleStateBasedOnEnabledProperty(module);
|
||||||
|
}
|
||||||
|
|
||||||
|
afterInitializationAction();
|
||||||
|
MessageLoop();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void MessageLoop()
|
||||||
|
{
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (GetMessageW(out MSG msg, IntPtr.Zero, 0, 0) != 0)
|
||||||
|
{
|
||||||
|
TranslateMessage(ref msg);
|
||||||
|
DispatchMessageW(ref msg);
|
||||||
|
|
||||||
|
switch (msg.Message)
|
||||||
|
{
|
||||||
|
case (uint)WindowMessages.HOTKEY:
|
||||||
|
HotkeyManager.ProcessHotkey(msg.WParam);
|
||||||
|
break;
|
||||||
|
case (uint)WindowMessages.ICON_NOTIFY:
|
||||||
|
TrayIconManager.ProcessTrayIconMessage(msg.LParam);
|
||||||
|
break;
|
||||||
|
case (uint)WindowMessages.COMMAND:
|
||||||
|
TrayIconManager.ProcessTrayMenuCommand(msg.WParam);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[DoesNotReturn]
|
||||||
|
internal static void Close()
|
||||||
|
{
|
||||||
|
foreach (IPowerToysModule module in _successfullyAddedModules)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
module.Disable();
|
||||||
|
if (module.HotkeyEx is not null)
|
||||||
|
{
|
||||||
|
HotkeyManager.DisableHotkey(module.HotkeyEx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"The module {module.Name} failed to unload: \n" + e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Environment.Exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ToggleModuleStateBasedOnEnabledProperty(IPowerToysModule module)
|
||||||
|
{
|
||||||
|
if ((module.Enabled && (module.GpoRuleConfigured != PowerToys.GPOWrapper.GpoRuleConfigured.Disabled)) || module.GpoRuleConfigured == PowerToys.GPOWrapper.GpoRuleConfigured.Enabled)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
module.Enable();
|
||||||
|
|
||||||
|
/* Todo: conflict manager */
|
||||||
|
|
||||||
|
if (module.HotkeyEx is not null)
|
||||||
|
{
|
||||||
|
HotkeyManager.EnableHotkey(module.HotkeyEx, module.OnHotkey);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"The module {module.Name} failed to load: \n" + e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
module.Disable();
|
||||||
|
|
||||||
|
if (module.HotkeyEx is not null)
|
||||||
|
{
|
||||||
|
HotkeyManager.DisableHotkey(module.HotkeyEx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
MessageBox.Show($"The module {module.Name} failed to unload: \n" + e.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void InitializeTrayWindow()
|
||||||
|
{
|
||||||
|
IntPtr hInstance = Process.GetCurrentProcess().MainModule!.BaseAddress;
|
||||||
|
IntPtr hCursor = Cursors.Arrow.Handle;
|
||||||
|
IntPtr hIcon = SystemIcons.Application.Handle;
|
||||||
|
|
||||||
|
var wc = new WNDCLASS
|
||||||
|
{
|
||||||
|
HCursor = hCursor,
|
||||||
|
HInstance = hInstance,
|
||||||
|
LpszClassName = TrayWindowClassName,
|
||||||
|
Style = CSHREDRAW | CSVREDRAW,
|
||||||
|
LpfnWndProc = TrayIconWindowProc,
|
||||||
|
HIcon = hIcon,
|
||||||
|
HbrBackground = IntPtr.Zero,
|
||||||
|
LpszMenuName = string.Empty,
|
||||||
|
CbClsExtra = 0,
|
||||||
|
CbWndExtra = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
_ = RegisterClassW(ref wc);
|
||||||
|
|
||||||
|
RunnerHwnd = CreateWindowExW(
|
||||||
|
0,
|
||||||
|
wc.LpszClassName,
|
||||||
|
TrayWindowClassName,
|
||||||
|
WSOVERLAPPEDWINDOW | WSPOPUP,
|
||||||
|
CWUSEDEFAULT,
|
||||||
|
CWUSEDEFAULT,
|
||||||
|
CWUSEDEFAULT,
|
||||||
|
CWUSEDEFAULT,
|
||||||
|
IntPtr.Zero,
|
||||||
|
IntPtr.Zero,
|
||||||
|
wc.HInstance,
|
||||||
|
IntPtr.Zero);
|
||||||
|
|
||||||
|
if (RunnerHwnd == IntPtr.Zero)
|
||||||
|
{
|
||||||
|
var err = Marshal.GetLastPInvokeError();
|
||||||
|
MessageBox.Show($"CreateWindowExW failed. LastError={err}", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IntPtr TrayIconWindowProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
|
||||||
|
{
|
||||||
|
TrayIconManager.ProcessTrayIconMessage(lParam.ToInt64());
|
||||||
|
return DefWindowProcW(hWnd, msg, wParam, lParam);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
20
src/RunnerV2/RunnerV2/RunnerV2.csproj
Normal file
20
src/RunnerV2/RunnerV2/RunnerV2.csproj
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<Import Project="..\..\Common.Dotnet.CsWinRT.props" />
|
||||||
|
<Import Project="..\..\Common.SelfContained.props" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<Description>PowerToys Runner</Description>
|
||||||
|
<AssemblyName>PowerToys2</AssemblyName>
|
||||||
|
<OutputPath>..\..\..\$(Platform)\$(Configuration)</OutputPath>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
|
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||||
|
<ApplicationIcon>icon.ico</ApplicationIcon>
|
||||||
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||||
|
<ProjectReference Include="..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
</Project>
|
||||||
18
src/RunnerV2/RunnerV2/app.manifest
Normal file
18
src/RunnerV2/RunnerV2/app.manifest
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
|
||||||
|
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
|
||||||
|
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||||
|
<security>
|
||||||
|
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
||||||
|
</requestedPrivileges>
|
||||||
|
</security>
|
||||||
|
</trustInfo>
|
||||||
|
|
||||||
|
<application xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
|
<windowsSettings>
|
||||||
|
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true/PM</dpiAware>
|
||||||
|
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
|
||||||
|
</windowsSettings>
|
||||||
|
</application>
|
||||||
|
</assembly>
|
||||||
BIN
src/RunnerV2/RunnerV2/icon.ico
Normal file
BIN
src/RunnerV2/RunnerV2/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
@@ -66,5 +66,10 @@ namespace PowerToys.GPOWrapperProjection
|
|||||||
{
|
{
|
||||||
return (GpoRuleConfigured)PowerToys.GPOWrapper.GPOWrapper.GetConfiguredWorkspacesEnabledValue();
|
return (GpoRuleConfigured)PowerToys.GPOWrapper.GPOWrapper.GetConfiguredWorkspacesEnabledValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static GpoRuleConfigured GetDisableShowWhatsNewAfterUpdatesValue()
|
||||||
|
{
|
||||||
|
return (GpoRuleConfigured)PowerToys.GPOWrapper.GPOWrapper.GetDisableShowWhatsNewAfterUpdatesValue();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
src/common/ManagedCommon/HotkeyEx.cs
Normal file
8
src/common/ManagedCommon/HotkeyEx.cs
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
// 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 ManagedCommon
|
||||||
|
{
|
||||||
|
public record HotkeyEx(ushort ModifiersMask, ushort VkCode);
|
||||||
|
}
|
||||||
29
src/common/ManagedCommon/IPowerToysModule.cs
Normal file
29
src/common/ManagedCommon/IPowerToysModule.cs
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// 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.Json;
|
||||||
|
using PowerToys.GPOWrapper;
|
||||||
|
|
||||||
|
namespace ManagedCommon
|
||||||
|
{
|
||||||
|
public interface IPowerToysModule
|
||||||
|
{
|
||||||
|
public string Name { get; }
|
||||||
|
|
||||||
|
public void Enable();
|
||||||
|
|
||||||
|
public void Disable();
|
||||||
|
|
||||||
|
public bool Enabled { get; }
|
||||||
|
|
||||||
|
public GpoRuleConfigured GpoRuleConfigured { get; }
|
||||||
|
|
||||||
|
public virtual HotkeyEx? HotkeyEx => null;
|
||||||
|
|
||||||
|
public virtual Action OnHotkey => () => { };
|
||||||
|
|
||||||
|
public virtual Action OnSettingsChanged(string settingsKind, JsonElement jsonProperties) => () => { };
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,7 +18,7 @@ namespace ManagedCommon
|
|||||||
internal sealed class OutGoingLanguageSettings
|
internal sealed class OutGoingLanguageSettings
|
||||||
{
|
{
|
||||||
[JsonPropertyName("language")]
|
[JsonPropertyName("language")]
|
||||||
public string LanguageTag { get; set; }
|
public string? LanguageTag { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string LoadLanguage()
|
public static string LoadLanguage()
|
||||||
@@ -36,7 +36,7 @@ namespace ManagedCommon
|
|||||||
inputStream.Close();
|
inputStream.Close();
|
||||||
reader.Dispose();
|
reader.Dispose();
|
||||||
|
|
||||||
return JsonSerializer.Deserialize<OutGoingLanguageSettings>(data, SourceGenerationContext.Default.OutGoingLanguageSettings).LanguageTag;
|
return JsonSerializer.Deserialize<OutGoingLanguageSettings>(data, SourceGenerationContext.Default.OutGoingLanguageSettings)!.LanguageTag!;
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,12 +29,12 @@ namespace ManagedCommon
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the path to the log directory for the current version of the app.
|
/// Gets the path to the log directory for the current version of the app.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string CurrentVersionLogDirectoryPath { get; private set; }
|
public static string? CurrentVersionLogDirectoryPath { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the path to the log directory for the app.
|
/// Gets the path to the log directory for the app.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static string AppLogDirectoryPath { get; private set; }
|
public static string? AppLogDirectoryPath { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes the logger and sets the path for logging.
|
/// Initializes the logger and sets the path for logging.
|
||||||
@@ -45,7 +45,7 @@ namespace ManagedCommon
|
|||||||
public static void InitializeLogger(string applicationLogPath, bool isLocalLow = false)
|
public static void InitializeLogger(string applicationLogPath, bool isLocalLow = false)
|
||||||
{
|
{
|
||||||
string versionedPath = LogDirectoryPath(applicationLogPath, isLocalLow);
|
string versionedPath = LogDirectoryPath(applicationLogPath, isLocalLow);
|
||||||
string basePath = Path.GetDirectoryName(versionedPath);
|
string basePath = Path.GetDirectoryName(versionedPath)!;
|
||||||
|
|
||||||
if (!Directory.Exists(versionedPath))
|
if (!Directory.Exists(versionedPath))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<Description>PowerToys ManagedCommon</Description>
|
<Description>PowerToys ManagedCommon</Description>
|
||||||
<AssemblyName>PowerToys.ManagedCommon</AssemblyName>
|
<AssemblyName>PowerToys.ManagedCommon</AssemblyName>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
|
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
|
||||||
@@ -20,6 +21,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\GPOWrapperProjection\GPOWrapperProjection.csproj" />
|
||||||
<ProjectReference Include="..\interop\PowerToys.Interop.vcxproj" />
|
<ProjectReference Include="..\interop\PowerToys.Interop.vcxproj" />
|
||||||
<ProjectReference Include="..\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
|
<ProjectReference Include="..\ManagedTelemetry\Telemetry\ManagedTelemetry.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace ManagedCommon
|
|||||||
// based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application
|
// based on https://stackoverflow.com/questions/51334674/how-to-detect-windows-10-light-dark-mode-in-win32-application
|
||||||
public static AppTheme GetAppTheme()
|
public static AppTheme GetAppTheme()
|
||||||
{
|
{
|
||||||
int value = (int)Registry.GetValue($"{HKeyRoot}\\{HkeyWindowsPersonalizeTheme}", HValueAppTheme, 1);
|
int value = (int)Registry.GetValue($"{HKeyRoot}\\{HkeyWindowsPersonalizeTheme}", HValueAppTheme, 1)!;
|
||||||
return (AppTheme)value;
|
return (AppTheme)value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ namespace ManagedCommon
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// An event that fires if the Theme changes.
|
/// An event that fires if the Theme changes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public event ThemeChangedEvent ThemeChanged;
|
public event ThemeChangedEvent? ThemeChanged;
|
||||||
|
|
||||||
private readonly ManagementEventWatcher watcher;
|
private readonly ManagementEventWatcher watcher;
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ namespace ManagedCommon
|
|||||||
var currentUser = WindowsIdentity.GetCurrent();
|
var currentUser = WindowsIdentity.GetCurrent();
|
||||||
var query = new WqlEventQuery(
|
var query = new WqlEventQuery(
|
||||||
$"SELECT * FROM RegistryValueChangeEvent WHERE Hive='HKEY_USERS' AND " +
|
$"SELECT * FROM RegistryValueChangeEvent WHERE Hive='HKEY_USERS' AND " +
|
||||||
$"KeyPath='{currentUser.User.Value}\\\\{ThemeHelpers.HkeyWindowsPersonalizeTheme.Replace("\\", "\\\\")}' AND ValueName='{ThemeHelpers.HValueAppTheme}'");
|
$"KeyPath='{currentUser.User?.Value}\\\\{ThemeHelpers.HkeyWindowsPersonalizeTheme.Replace("\\", "\\\\")}' AND ValueName='{ThemeHelpers.HValueAppTheme}'");
|
||||||
watcher = new ManagementEventWatcher(query);
|
watcher = new ManagementEventWatcher(query);
|
||||||
watcher.EventArrived += Watcher_EventArrived;
|
watcher.EventArrived += Watcher_EventArrived;
|
||||||
watcher.Start();
|
watcher.Start();
|
||||||
|
|||||||
@@ -52,13 +52,6 @@
|
|||||||
<Content Include="Assets\Hosts\Hosts.ico" />
|
<Content Include="Assets\Hosts\Hosts.ico" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<!-- 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>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.Extensions.Hosting" />
|
<PackageReference Include="Microsoft.Extensions.Hosting" />
|
||||||
<PackageReference Include="Microsoft.WindowsAppSDK" />
|
<PackageReference Include="Microsoft.WindowsAppSDK" />
|
||||||
@@ -83,7 +76,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\..\common\Common.UI\Common.UI.csproj" />
|
<ProjectReference Include="..\..\..\common\Common.UI\Common.UI.csproj" />
|
||||||
<ProjectReference Include="..\..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
<ProjectReference Include="..\..\..\common\GPOWrapperProjection\GPOWrapperProjection.csproj" />
|
||||||
<ProjectReference Include="..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
<ProjectReference Include="..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||||
<ProjectReference Include="..\..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" />
|
<ProjectReference Include="..\..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" />
|
||||||
<ProjectReference Include="..\..\..\common\interop\PowerToys.Interop.vcxproj" />
|
<ProjectReference Include="..\..\..\common\interop\PowerToys.Interop.vcxproj" />
|
||||||
|
|||||||
34
src/modules/Hosts/Hosts/ModuleInterface.cs
Normal file
34
src/modules/Hosts/Hosts/ModuleInterface.cs
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
// 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.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using ManagedCommon;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Library;
|
||||||
|
using PowerToys.GPOWrapper;
|
||||||
|
|
||||||
|
namespace Hosts
|
||||||
|
{
|
||||||
|
internal sealed class ModuleInterface : IPowerToysModule
|
||||||
|
{
|
||||||
|
public bool Enabled => new SettingsUtils().GetSettingsOrDefault<GeneralSettings>().Enabled.Hosts;
|
||||||
|
|
||||||
|
public GpoRuleConfigured GpoRuleConfigured => GpoRuleConfigured.NotConfigured;
|
||||||
|
|
||||||
|
public string Name => "Hosts";
|
||||||
|
|
||||||
|
public void Disable()
|
||||||
|
{
|
||||||
|
foreach (var process in Process.GetProcessesByName("PowerToys.Hosts.exe"))
|
||||||
|
{
|
||||||
|
process.Kill();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Enable()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
#include "resource.h"
|
|
||||||
#include "../../../common/version/version.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#include "winres.h"
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
1 VERSIONINFO
|
|
||||||
FILEVERSION FILE_VERSION
|
|
||||||
PRODUCTVERSION PRODUCT_VERSION
|
|
||||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
|
||||||
#ifdef _DEBUG
|
|
||||||
FILEFLAGS VS_FF_DEBUG
|
|
||||||
#else
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
#endif
|
|
||||||
FILEOS VOS_NT_WINDOWS32
|
|
||||||
FILETYPE VFT_DLL
|
|
||||||
FILESUBTYPE VFT2_UNKNOWN
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
|
|
||||||
BEGIN
|
|
||||||
VALUE "CompanyName", COMPANY_NAME
|
|
||||||
VALUE "FileDescription", FILE_DESCRIPTION
|
|
||||||
VALUE "FileVersion", FILE_VERSION_STRING
|
|
||||||
VALUE "InternalName", INTERNAL_NAME
|
|
||||||
VALUE "LegalCopyright", COPYRIGHT_NOTE
|
|
||||||
VALUE "OriginalFilename", ORIGINAL_FILENAME
|
|
||||||
VALUE "ProductName", PRODUCT_NAME
|
|
||||||
VALUE "ProductVersion", PRODUCT_VERSION_STRING
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
|
|
||||||
END
|
|
||||||
END
|
|
||||||
@@ -1,93 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" />
|
|
||||||
<Target Name="GenerateResourceFiles" BeforeTargets="PrepareForBuild">
|
|
||||||
<Exec Command="powershell -NonInteractive -executionpolicy Unrestricted ..\..\..\..\tools\build\convert-resx-to-rc.ps1 $(MSBuildThisFileDirectory) resource.base.h resource.h HostsModuleInterface.base.rc HostsModuleInterface.rc" />
|
|
||||||
</Target>
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<VCProjectVersion>16.0</VCProjectVersion>
|
|
||||||
<ProjectGuid>{B41B888C-7DB8-4747-B262-4062E05A230D}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>HostsModuleInterface</RootNamespace>
|
|
||||||
<ProjectName>HostsModuleInterface</ProjectName>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>true</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<UseDebugLibraries>false</UseDebugLibraries>
|
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
|
||||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
|
||||||
<CharacterSet>Unicode</CharacterSet>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="Shared">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="PropertySheets">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutDir>..\..\..\..\$(Platform)\$(Configuration)\WinUI3Apps\</OutDir>
|
|
||||||
<TargetName>PowerToys.HostsModuleInterface</TargetName>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
|
|
||||||
<LinkIncremental>true</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)'=='Release'">
|
|
||||||
<LinkIncremental>false</LinkIncremental>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup>
|
|
||||||
<ClCompile>
|
|
||||||
<AdditionalIncludeDirectories>..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="packages.config" />
|
|
||||||
<None Include="resource.base.h" />
|
|
||||||
<ClInclude Include="Generated Files\resource.h" />
|
|
||||||
<ClInclude Include="trace.h" />
|
|
||||||
<ClInclude Include="pch.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="trace.cpp" />
|
|
||||||
<ClCompile Include="pch.cpp">
|
|
||||||
<PrecompiledHeader Condition="'$(UsePrecompiledHeaders)' != 'false'">Create</PrecompiledHeader>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="dllmain.cpp" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
|
|
||||||
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\..\..\common\SettingsAPI\SettingsAPI.vcxproj">
|
|
||||||
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="HostsModuleInterface.base.rc" />
|
|
||||||
<ResourceCompile Include="Generated Files\HostsModuleInterface.rc" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="Resource.resx" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
|
||||||
</ImportGroup>
|
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
|
||||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="Source Files">
|
|
||||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
|
||||||
<Extensions>cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Header Files">
|
|
||||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
|
||||||
<Extensions>h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Resource Files">
|
|
||||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
|
||||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Generated Files">
|
|
||||||
<UniqueIdentifier>{875a08c6-f610-4667-bd0f-80171ed96072}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="pch.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="dllmain.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="trace.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="HostsModuleInterface.base.rc">
|
|
||||||
<Filter>Resource Files</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="Resource.resx">
|
|
||||||
<Filter>Resource Files</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="resource.base.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</None>
|
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="pch.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Generated Files\resource.h">
|
|
||||||
<Filter>Generated Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="trace.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ResourceCompile Include="Generated Files\HostsModuleInterface.rc">
|
|
||||||
<Filter>Resource Files</Filter>
|
|
||||||
</ResourceCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -1,124 +0,0 @@
|
|||||||
<?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="Hosts_Name" xml:space="preserve">
|
|
||||||
<value>Hosts File Editor</value>
|
|
||||||
<comment>"Hosts" refer to the system hosts file, do not loc</comment>
|
|
||||||
</data>
|
|
||||||
</root>
|
|
||||||
@@ -1,300 +0,0 @@
|
|||||||
#include "pch.h"
|
|
||||||
|
|
||||||
#include "trace.h"
|
|
||||||
#include <common/logger/logger.h>
|
|
||||||
#include <common/utils/logger_helper.h>
|
|
||||||
#include <interface/powertoy_module_interface.h>
|
|
||||||
#include "Generated Files/resource.h"
|
|
||||||
|
|
||||||
#include <shellapi.h>
|
|
||||||
#include <common/interop/shared_constants.h>
|
|
||||||
#include <common/utils/EventWaiter.h>
|
|
||||||
#include <common/utils/resources.h>
|
|
||||||
#include <common/utils/winapi_error.h>
|
|
||||||
#include <common/SettingsAPI/settings_objects.h>
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
extern "C" IMAGE_DOS_HEADER __ImageBase;
|
|
||||||
|
|
||||||
BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lpReserved*/)
|
|
||||||
{
|
|
||||||
switch (ul_reason_for_call)
|
|
||||||
{
|
|
||||||
case DLL_PROCESS_ATTACH:
|
|
||||||
Trace::RegisterProvider();
|
|
||||||
break;
|
|
||||||
case DLL_THREAD_ATTACH:
|
|
||||||
case DLL_THREAD_DETACH:
|
|
||||||
break;
|
|
||||||
case DLL_PROCESS_DETACH:
|
|
||||||
Trace::UnregisterProvider();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
// Name of the powertoy module.
|
|
||||||
inline const std::wstring ModuleKey = L"Hosts";
|
|
||||||
}
|
|
||||||
|
|
||||||
class HostsModuleInterface : public PowertoyModuleIface
|
|
||||||
{
|
|
||||||
private:
|
|
||||||
bool m_enabled = false;
|
|
||||||
|
|
||||||
std::wstring app_name;
|
|
||||||
|
|
||||||
//contains the non localized key of the powertoy
|
|
||||||
std::wstring app_key;
|
|
||||||
|
|
||||||
HANDLE m_hProcess = nullptr;
|
|
||||||
|
|
||||||
HANDLE m_hShowEvent{};
|
|
||||||
|
|
||||||
HANDLE m_hShowAdminEvent{};
|
|
||||||
|
|
||||||
HANDLE m_hTerminateEvent{};
|
|
||||||
|
|
||||||
bool is_process_running()
|
|
||||||
{
|
|
||||||
return WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bring_process_to_front()
|
|
||||||
{
|
|
||||||
auto enum_windows = [](HWND hwnd, LPARAM param) -> BOOL {
|
|
||||||
HANDLE process_handle = reinterpret_cast<HANDLE>(param);
|
|
||||||
DWORD window_process_id = 0;
|
|
||||||
|
|
||||||
GetWindowThreadProcessId(hwnd, &window_process_id);
|
|
||||||
if (GetProcessId(process_handle) == window_process_id)
|
|
||||||
{
|
|
||||||
SetForegroundWindow(hwnd);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
};
|
|
||||||
|
|
||||||
EnumWindows(enum_windows, (LPARAM)m_hProcess);
|
|
||||||
}
|
|
||||||
|
|
||||||
void launch_process(bool runas)
|
|
||||||
{
|
|
||||||
Logger::trace(L"Starting Hosts process");
|
|
||||||
unsigned long powertoys_pid = GetCurrentProcessId();
|
|
||||||
|
|
||||||
std::wstring executable_args = L"";
|
|
||||||
executable_args.append(std::to_wstring(powertoys_pid));
|
|
||||||
|
|
||||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
|
||||||
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
|
|
||||||
sei.lpFile = L"WinUI3Apps\\PowerToys.Hosts.exe";
|
|
||||||
sei.nShow = SW_SHOWNORMAL;
|
|
||||||
sei.lpParameters = executable_args.data();
|
|
||||||
|
|
||||||
if (runas)
|
|
||||||
{
|
|
||||||
sei.lpVerb = L"runas";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ShellExecuteExW(&sei))
|
|
||||||
{
|
|
||||||
Logger::trace("Successfully started the Hosts process");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger::error(L"Hosts failed to start. {}", get_last_error_or_default(GetLastError()));
|
|
||||||
}
|
|
||||||
|
|
||||||
m_hProcess = sei.hProcess;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
EventWaiter m_showEventWaiter;
|
|
||||||
|
|
||||||
EventWaiter m_showAdminEventWaiter;
|
|
||||||
|
|
||||||
HostsModuleInterface()
|
|
||||||
{
|
|
||||||
app_name = GET_RESOURCE_STRING(IDS_HOSTS_NAME);
|
|
||||||
app_key = ModuleKey;
|
|
||||||
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_hShowAdminEvent)
|
|
||||||
{
|
|
||||||
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_hTerminateEvent = CreateDefaultEvent(CommonSharedConstants::TERMINATE_HOSTS_EVENT);
|
|
||||||
if (!m_hTerminateEvent)
|
|
||||||
{
|
|
||||||
Logger::error(L"Failed to create terminate hosts 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);
|
|
||||||
|
|
||||||
if (is_process_running())
|
|
||||||
{
|
|
||||||
bring_process_to_front();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
launch_process(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Trace::ActivateEditor();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
if (is_process_running())
|
|
||||||
{
|
|
||||||
bring_process_to_front();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
launch_process(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
Trace::ActivateEditor();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
~HostsModuleInterface()
|
|
||||||
{
|
|
||||||
m_enabled = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroy the powertoy and free memory
|
|
||||||
virtual void destroy() override
|
|
||||||
{
|
|
||||||
Logger::trace("HostsModuleInterface::destroy()");
|
|
||||||
|
|
||||||
if (m_hShowEvent)
|
|
||||||
{
|
|
||||||
CloseHandle(m_hShowEvent);
|
|
||||||
m_hShowEvent = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_hShowAdminEvent)
|
|
||||||
{
|
|
||||||
CloseHandle(m_hShowAdminEvent);
|
|
||||||
m_hShowAdminEvent = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_hTerminateEvent)
|
|
||||||
{
|
|
||||||
CloseHandle(m_hTerminateEvent);
|
|
||||||
m_hTerminateEvent = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the localized display name of the powertoy
|
|
||||||
virtual const wchar_t* get_name() override
|
|
||||||
{
|
|
||||||
return app_name.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the non localized key of the powertoy, this will be cached by the runner
|
|
||||||
virtual const wchar_t* get_key() override
|
|
||||||
{
|
|
||||||
return app_key.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the configured status for the gpo policy for the module
|
|
||||||
virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override
|
|
||||||
{
|
|
||||||
return powertoys_gpo::getConfiguredHostsFileEditorEnabledValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool get_config(wchar_t* /*buffer*/, int* /*buffer_size*/) override
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void call_custom_action(const wchar_t* /*action*/) override
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void set_config(const wchar_t* /*config*/) override
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool is_enabled() override
|
|
||||||
{
|
|
||||||
return m_enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void enable()
|
|
||||||
{
|
|
||||||
Logger::trace("HostsModuleInterface::enable()");
|
|
||||||
m_enabled = true;
|
|
||||||
Trace::EnableHostsFileEditor(true);
|
|
||||||
};
|
|
||||||
|
|
||||||
virtual void disable()
|
|
||||||
{
|
|
||||||
Logger::trace("HostsModuleInterface::disable()");
|
|
||||||
if (m_enabled)
|
|
||||||
{
|
|
||||||
if (m_hShowEvent)
|
|
||||||
{
|
|
||||||
ResetEvent(m_hShowEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_hShowAdminEvent)
|
|
||||||
{
|
|
||||||
ResetEvent(m_hShowAdminEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetEvent(m_hTerminateEvent);
|
|
||||||
WaitForSingleObject(m_hProcess, 1500);
|
|
||||||
TerminateProcess(m_hProcess, 1);
|
|
||||||
ResetEvent(m_hTerminateEvent);
|
|
||||||
}
|
|
||||||
|
|
||||||
m_enabled = false;
|
|
||||||
Trace::EnableHostsFileEditor(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
|
|
||||||
{
|
|
||||||
return new HostsModuleInterface();
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.240111.5" targetFramework="native" />
|
|
||||||
</packages>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
#include "pch.h"
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN
|
|
||||||
#include <windows.h>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Visual C++ generated include file.
|
|
||||||
// Used by AlwaysOnTopModuleInterface.rc
|
|
||||||
|
|
||||||
//////////////////////////////
|
|
||||||
// Non-localizable
|
|
||||||
|
|
||||||
#define FILE_DESCRIPTION "PowerToys Hosts Module"
|
|
||||||
#define INTERNAL_NAME "PowerToys.HostsModuleInterface"
|
|
||||||
#define ORIGINAL_FILENAME "PowerToys.HostsModuleInterface.dll"
|
|
||||||
|
|
||||||
// Non-localizable
|
|
||||||
//////////////////////////////
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#include "pch.h"
|
|
||||||
#include "trace.h"
|
|
||||||
|
|
||||||
#include <common/Telemetry/TraceBase.h>
|
|
||||||
|
|
||||||
TRACELOGGING_DEFINE_PROVIDER(
|
|
||||||
g_hProvider,
|
|
||||||
"Microsoft.PowerToys",
|
|
||||||
// {38e8889b-9731-53f5-e901-e8a7c1753074}
|
|
||||||
(0x38e8889b, 0x9731, 0x53f5, 0xe9, 0x01, 0xe8, 0xa7, 0xc1, 0x75, 0x30, 0x74),
|
|
||||||
TraceLoggingOptionProjectTelemetry());
|
|
||||||
|
|
||||||
// Log if the user has HostsFileEditor enabled or disabled
|
|
||||||
void Trace::EnableHostsFileEditor(const bool enabled) noexcept
|
|
||||||
{
|
|
||||||
TraceLoggingWriteWrapper(
|
|
||||||
g_hProvider,
|
|
||||||
"HostsFileEditor_EnableHostsFileEditor",
|
|
||||||
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
|
||||||
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE),
|
|
||||||
TraceLoggingBoolean(enabled, "Enabled"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log that the user tried to activate the editor
|
|
||||||
void Trace::ActivateEditor() noexcept
|
|
||||||
{
|
|
||||||
TraceLoggingWriteWrapper(
|
|
||||||
g_hProvider,
|
|
||||||
"HostsFileEditor_Activate",
|
|
||||||
ProjectTelemetryPrivacyDataTag(ProjectTelemetryTag_ProductAndServicePerformance),
|
|
||||||
TraceLoggingKeyword(PROJECT_KEYWORD_MEASURE));
|
|
||||||
}
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <common/Telemetry/TraceBase.h>
|
|
||||||
|
|
||||||
class Trace : public telemetry::TraceBase
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Log if the user has HostsFileEditor enabled or disabled
|
|
||||||
static void EnableHostsFileEditor(const bool enabled) noexcept;
|
|
||||||
|
|
||||||
// Log that the user tried to activate the editor
|
|
||||||
static void ActivateEditor() noexcept;
|
|
||||||
};
|
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<Import Project="..\..\..\Common.Dotnet.CsWinRT.props" />
|
||||||
|
<Import Project="..\..\..\Common.SelfContained.props" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Description>PowerToys Alway on Top module interface</Description>
|
||||||
|
<AssemblyName>PowerToys.AlwaysOnTopModuleInterface</AssemblyName>
|
||||||
|
<OutputPath>..\..\..\..\$(Platform)\$(Configuration)</OutputPath>
|
||||||
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
|
<AppendRuntimeIdentifierToOutputPath>false</AppendRuntimeIdentifierToOutputPath>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||||
|
<ProjectReference Include="..\..\..\settings-ui\Settings.UI.Library\Settings.UI.Library.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
#include <windows.h>
|
|
||||||
#include "resource.h"
|
|
||||||
#include "../../../common/version/version.h"
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
#include "winres.h"
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
1 VERSIONINFO
|
|
||||||
FILEVERSION FILE_VERSION
|
|
||||||
PRODUCTVERSION PRODUCT_VERSION
|
|
||||||
FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
|
|
||||||
#ifdef _DEBUG
|
|
||||||
FILEFLAGS VS_FF_DEBUG
|
|
||||||
#else
|
|
||||||
FILEFLAGS 0x0L
|
|
||||||
#endif
|
|
||||||
FILEOS VOS_NT_WINDOWS32
|
|
||||||
FILETYPE VFT_DLL
|
|
||||||
FILESUBTYPE VFT2_UNKNOWN
|
|
||||||
BEGIN
|
|
||||||
BLOCK "StringFileInfo"
|
|
||||||
BEGIN
|
|
||||||
BLOCK "040904b0" // US English (0x0409), Unicode (0x04B0) charset
|
|
||||||
BEGIN
|
|
||||||
VALUE "CompanyName", COMPANY_NAME
|
|
||||||
VALUE "FileDescription", FILE_DESCRIPTION
|
|
||||||
VALUE "FileVersion", FILE_VERSION_STRING
|
|
||||||
VALUE "InternalName", INTERNAL_NAME
|
|
||||||
VALUE "LegalCopyright", COPYRIGHT_NOTE
|
|
||||||
VALUE "OriginalFilename", ORIGINAL_FILENAME
|
|
||||||
VALUE "ProductName", PRODUCT_NAME
|
|
||||||
VALUE "ProductVersion", PRODUCT_VERSION_STRING
|
|
||||||
END
|
|
||||||
END
|
|
||||||
BLOCK "VarFileInfo"
|
|
||||||
BEGIN
|
|
||||||
VALUE "Translation", 0x409, 1200 // US English (0x0409), Unicode (1200) charset
|
|
||||||
END
|
|
||||||
END
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" />
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<VCProjectVersion>15.0</VCProjectVersion>
|
|
||||||
<ProjectGuid>{48A0A19E-A0BE-4256-ACF8-CC3B80291AF9}</ProjectGuid>
|
|
||||||
<Keyword>Win32Proj</Keyword>
|
|
||||||
<RootNamespace>alwaysontop</RootNamespace>
|
|
||||||
<ProjectName>AlwaysOnTopModuleInterface</ProjectName>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
|
||||||
<PropertyGroup Label="Configuration">
|
|
||||||
<ConfigurationType>DynamicLibrary</ConfigurationType>
|
|
||||||
<PlatformToolset>v143</PlatformToolset>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
|
||||||
<ImportGroup Label="ExtensionSettings">
|
|
||||||
</ImportGroup>
|
|
||||||
<ImportGroup Label="Shared" />
|
|
||||||
<ImportGroup Label="PropertySheets">
|
|
||||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
|
||||||
</ImportGroup>
|
|
||||||
<PropertyGroup Label="UserMacros" />
|
|
||||||
<PropertyGroup>
|
|
||||||
<OutDir>..\..\..\..\$(Platform)\$(Configuration)\</OutDir>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup>
|
|
||||||
<TargetName>PowerToys.AlwaysOnTopModuleInterface</TargetName>
|
|
||||||
</PropertyGroup>
|
|
||||||
<ItemDefinitionGroup>
|
|
||||||
<ClCompile>
|
|
||||||
<PreprocessorDefinitions>_WINDOWS;_USRDLL;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
|
||||||
<AdditionalIncludeDirectories>..\;..\..\..\common\inc;..\..\..\common\Telemetry;..\..\;..\..\..\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
|
||||||
</ClCompile>
|
|
||||||
<Link>
|
|
||||||
<OutputFile>$(OutDir)$(TargetName)$(TargetExt)</OutputFile>
|
|
||||||
<AdditionalDependencies>gdiplus.lib;dwmapi.lib;shlwapi.lib;uxtheme.lib;shcore.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
|
||||||
</Link>
|
|
||||||
</ItemDefinitionGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="..\AlwaysOnTop\trace.h" />
|
|
||||||
<ClInclude Include="pch.h" />
|
|
||||||
<ClInclude Include="resource.h" />
|
|
||||||
<ClInclude Include="targetver.h" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="..\AlwaysOnTop\trace.cpp" />
|
|
||||||
<ClCompile Include="dllmain.cpp" />
|
|
||||||
<ClCompile Include="pch.cpp">
|
|
||||||
<PrecompiledHeader Condition="'$(UsePrecompiledHeaders)' != 'false'">Create</PrecompiledHeader>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\..\..\common\logger\logger.vcxproj">
|
|
||||||
<Project>{d9b8fc84-322a-4f9f-bbb9-20915c47ddfd}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
<ProjectReference Include="..\..\..\common\SettingsAPI\SettingsAPI.vcxproj">
|
|
||||||
<Project>{6955446d-23f7-4023-9bb3-8657f904af99}</Project>
|
|
||||||
</ProjectReference>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ResourceCompile Include="AlwaysOnTopModuleInterface.rc" />
|
|
||||||
</ItemGroup>
|
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
|
||||||
<ImportGroup Label="ExtensionTargets">
|
|
||||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.211019.2\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
|
||||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
|
||||||
<Import Project="..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets" Condition="Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" />
|
|
||||||
</ImportGroup>
|
|
||||||
<Import Project="..\..\..\..\deps\spdlog.props" />
|
|
||||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
|
||||||
<PropertyGroup>
|
|
||||||
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
|
||||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.CppWinRT.2.0.240111.5\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
|
||||||
<Error Condition="!Exists('..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\..\..\packages\Microsoft.Windows.ImplementationLibrary.1.0.231216.1\build\native\Microsoft.Windows.ImplementationLibrary.targets'))" />
|
|
||||||
</Target>
|
|
||||||
</Project>
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<ItemGroup>
|
|
||||||
<ClCompile Include="pch.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="dllmain.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="..\AlwaysOnTop\trace.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ClInclude Include="targetver.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="pch.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="..\AlwaysOnTop\trace.h">
|
|
||||||
<Filter>Header Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="resource.h">
|
|
||||||
<Filter>Resource Files</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Filter Include="Source Files">
|
|
||||||
<UniqueIdentifier>{21926bf1-03b3-482d-8f60-8bc4fbfc6564}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Header Files">
|
|
||||||
<UniqueIdentifier>{2f10207d-d8d1-4a42-8027-8ca597b3cb23}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Resource Files">
|
|
||||||
<UniqueIdentifier>{a4241930-ecae-44e2-be82-25eff2499fcd}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
<Filter Include="Generated Files">
|
|
||||||
<UniqueIdentifier>{8d479404-964b-4eb1-8fe8-554be3e68c9b}</UniqueIdentifier>
|
|
||||||
</Filter>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<None Include="packages.config" />
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<ResourceCompile Include="AlwaysOnTopModuleInterface.rc">
|
|
||||||
<Filter>Resource Files</Filter>
|
|
||||||
</ResourceCompile>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
|
||||||
<Natvis Include="$(MSBuildThisFileDirectory)..\..\natvis\wil.natvis" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
||||||
@@ -0,0 +1,72 @@
|
|||||||
|
// 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.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using ManagedCommon;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Library;
|
||||||
|
using PowerToys.GPOWrapper;
|
||||||
|
|
||||||
|
namespace AlwaysOnTopModuleInterface
|
||||||
|
{
|
||||||
|
public class ModuleInterface : IPowerToysModule
|
||||||
|
{
|
||||||
|
public bool Enabled => true;
|
||||||
|
|
||||||
|
public string Name => "AlwaysOnTop";
|
||||||
|
|
||||||
|
public GpoRuleConfigured GpoRuleConfigured => GpoRuleConfigured.Unavailable;
|
||||||
|
|
||||||
|
private Process? _process;
|
||||||
|
|
||||||
|
private IntPtr pinEvent = CreateEventW(IntPtr.Zero, false, false, "Local\\AlwaysOnTopPinEvent-892e0aa2-cfa8-4cc4-b196-ddeb32314ce8");
|
||||||
|
|
||||||
|
public void Disable()
|
||||||
|
{
|
||||||
|
if (_process is not null && !_process.HasExited)
|
||||||
|
{
|
||||||
|
_process.Kill();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pinEvent != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
CloseHandle(pinEvent);
|
||||||
|
pinEvent = IntPtr.Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Enable()
|
||||||
|
{
|
||||||
|
var psi = new ProcessStartInfo
|
||||||
|
{
|
||||||
|
FileName = "PowerToys.AlwaysOnTop.exe",
|
||||||
|
Arguments = Environment.ProcessId.ToString(CultureInfo.InvariantCulture),
|
||||||
|
UseShellExecute = true,
|
||||||
|
};
|
||||||
|
|
||||||
|
_process = Process.Start(psi);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HotkeyEx HotkeyEx => new(0x2 | 0x1, 0x54); // Ctrl + Alt + T
|
||||||
|
|
||||||
|
public Action OnHotkey => () =>
|
||||||
|
{
|
||||||
|
if (_process is not null && !_process.HasExited && pinEvent != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
_ = SetEvent(pinEvent);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
|
||||||
|
internal static extern IntPtr CreateEventW(IntPtr lpEventAttributes, bool bManualReset, bool bInitialState, string lpName);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
internal static extern bool CloseHandle(IntPtr hObject);
|
||||||
|
|
||||||
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
|
internal static extern bool SetEvent(IntPtr hEvent);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,300 +0,0 @@
|
|||||||
#include "pch.h"
|
|
||||||
|
|
||||||
#include <interface/powertoy_module_interface.h>
|
|
||||||
|
|
||||||
#include <common/logger/logger.h>
|
|
||||||
#include <common/utils/resources.h>
|
|
||||||
#include <common/utils/winapi_error.h>
|
|
||||||
|
|
||||||
#include <AlwaysOnTop/trace.h>
|
|
||||||
#include <AlwaysOnTop/ModuleConstants.h>
|
|
||||||
|
|
||||||
#include <shellapi.h>
|
|
||||||
#include <common/SettingsAPI/settings_objects.h>
|
|
||||||
#include <common/interop/shared_constants.h>
|
|
||||||
|
|
||||||
namespace NonLocalizable
|
|
||||||
{
|
|
||||||
const wchar_t ModulePath[] = L"PowerToys.AlwaysOnTop.exe";
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
const wchar_t JSON_KEY_PROPERTIES[] = L"properties";
|
|
||||||
const wchar_t JSON_KEY_WIN[] = L"win";
|
|
||||||
const wchar_t JSON_KEY_ALT[] = L"alt";
|
|
||||||
const wchar_t JSON_KEY_CTRL[] = L"ctrl";
|
|
||||||
const wchar_t JSON_KEY_SHIFT[] = L"shift";
|
|
||||||
const wchar_t JSON_KEY_CODE[] = L"code";
|
|
||||||
const wchar_t JSON_KEY_HOTKEY[] = L"hotkey";
|
|
||||||
const wchar_t JSON_KEY_VALUE[] = L"value";
|
|
||||||
}
|
|
||||||
|
|
||||||
BOOL APIENTRY DllMain(HMODULE /*hModule*/, DWORD ul_reason_for_call, LPVOID /*lpReserved*/)
|
|
||||||
{
|
|
||||||
switch (ul_reason_for_call)
|
|
||||||
{
|
|
||||||
case DLL_PROCESS_ATTACH:
|
|
||||||
Trace::AlwaysOnTop::RegisterProvider();
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DLL_THREAD_ATTACH:
|
|
||||||
case DLL_THREAD_DETACH:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DLL_PROCESS_DETACH:
|
|
||||||
Trace::AlwaysOnTop::UnregisterProvider();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
class AlwaysOnTopModuleInterface : public PowertoyModuleIface
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
// Return the localized display name of the powertoy
|
|
||||||
virtual PCWSTR get_name() override
|
|
||||||
{
|
|
||||||
return app_name.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the non localized key of the powertoy, this will be cached by the runner
|
|
||||||
virtual const wchar_t* get_key() override
|
|
||||||
{
|
|
||||||
return app_key.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the configured status for the gpo policy for the module
|
|
||||||
virtual powertoys_gpo::gpo_rule_configured_t gpo_policy_enabled_configuration() override
|
|
||||||
{
|
|
||||||
return powertoys_gpo::getConfiguredAlwaysOnTopEnabledValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return JSON with the configuration options.
|
|
||||||
// These are the settings shown on the settings page along with their current values.
|
|
||||||
virtual bool get_config(wchar_t* buffer, int* buffer_size) override
|
|
||||||
{
|
|
||||||
HINSTANCE hinstance = reinterpret_cast<HINSTANCE>(&__ImageBase);
|
|
||||||
|
|
||||||
// Create a Settings object.
|
|
||||||
PowerToysSettings::Settings settings(hinstance, get_name());
|
|
||||||
|
|
||||||
return settings.serialize_to_buffer(buffer, buffer_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Passes JSON with the configuration settings for the powertoy.
|
|
||||||
// This is called when the user hits Save on the settings page.
|
|
||||||
virtual void set_config(const wchar_t* config) override
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Parse the input JSON string.
|
|
||||||
PowerToysSettings::PowerToyValues values =
|
|
||||||
PowerToysSettings::PowerToyValues::from_json_string(config, get_key());
|
|
||||||
|
|
||||||
parse_hotkey(values);
|
|
||||||
// If you don't need to do any custom processing of the settings, proceed
|
|
||||||
// to persists the values calling:
|
|
||||||
values.save_to_settings_file();
|
|
||||||
// Otherwise call a custom function to process the settings before saving them to disk:
|
|
||||||
// save_settings();
|
|
||||||
}
|
|
||||||
catch (std::exception&)
|
|
||||||
{
|
|
||||||
// Improper JSON.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual bool on_hotkey(size_t /*hotkeyId*/) override
|
|
||||||
{
|
|
||||||
if (m_enabled)
|
|
||||||
{
|
|
||||||
Logger::trace(L"AlwaysOnTop hotkey pressed");
|
|
||||||
if (!is_process_running())
|
|
||||||
{
|
|
||||||
Enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
SetEvent(m_hPinEvent);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual size_t get_hotkeys(Hotkey* hotkeys, size_t buffer_size) override
|
|
||||||
{
|
|
||||||
if (m_hotkey.key)
|
|
||||||
{
|
|
||||||
if (hotkeys && buffer_size >= 1)
|
|
||||||
{
|
|
||||||
hotkeys[0] = m_hotkey;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Enable the powertoy
|
|
||||||
virtual void enable()
|
|
||||||
{
|
|
||||||
Logger::info("AlwaysOnTop enabling");
|
|
||||||
|
|
||||||
Enable();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Disable the powertoy
|
|
||||||
virtual void disable()
|
|
||||||
{
|
|
||||||
Logger::info("AlwaysOnTop disabling");
|
|
||||||
|
|
||||||
Disable(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns if the powertoy is enabled
|
|
||||||
virtual bool is_enabled() override
|
|
||||||
{
|
|
||||||
return m_enabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Destroy the powertoy and free memory
|
|
||||||
virtual void destroy() override
|
|
||||||
{
|
|
||||||
Disable(false);
|
|
||||||
delete this;
|
|
||||||
}
|
|
||||||
|
|
||||||
AlwaysOnTopModuleInterface()
|
|
||||||
{
|
|
||||||
app_name = L"AlwaysOnTop"; //TODO: localize
|
|
||||||
app_key = NonLocalizable::ModuleKey;
|
|
||||||
m_hPinEvent = CreateDefaultEvent(CommonSharedConstants::ALWAYS_ON_TOP_PIN_EVENT);
|
|
||||||
m_hTerminateEvent = CreateDefaultEvent(CommonSharedConstants::ALWAYS_ON_TOP_TERMINATE_EVENT);
|
|
||||||
init_settings();
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
void Enable()
|
|
||||||
{
|
|
||||||
m_enabled = true;
|
|
||||||
|
|
||||||
// Log telemetry
|
|
||||||
Trace::AlwaysOnTop::Enable(true);
|
|
||||||
|
|
||||||
unsigned long powertoys_pid = GetCurrentProcessId();
|
|
||||||
std::wstring executable_args = L"";
|
|
||||||
executable_args.append(std::to_wstring(powertoys_pid));
|
|
||||||
ResetEvent(m_hPinEvent);
|
|
||||||
|
|
||||||
SHELLEXECUTEINFOW sei{ sizeof(sei) };
|
|
||||||
sei.fMask = { SEE_MASK_NOCLOSEPROCESS | SEE_MASK_FLAG_NO_UI };
|
|
||||||
sei.lpFile = NonLocalizable::ModulePath;
|
|
||||||
sei.nShow = SW_SHOWNORMAL;
|
|
||||||
sei.lpParameters = executable_args.data();
|
|
||||||
if (ShellExecuteExW(&sei) == false)
|
|
||||||
{
|
|
||||||
Logger::error(L"Failed to start AlwaysOnTop");
|
|
||||||
auto message = get_last_error_message(GetLastError());
|
|
||||||
if (message.has_value())
|
|
||||||
{
|
|
||||||
Logger::error(message.value());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_hProcess = sei.hProcess;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Disable(bool const traceEvent)
|
|
||||||
{
|
|
||||||
m_enabled = false;
|
|
||||||
ResetEvent(m_hPinEvent);
|
|
||||||
|
|
||||||
// Log telemetry
|
|
||||||
if (traceEvent)
|
|
||||||
{
|
|
||||||
Trace::AlwaysOnTop::Enable(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetEvent(m_hTerminateEvent);
|
|
||||||
|
|
||||||
// Wait for 1.5 seconds for the process to end correctly and stop etw tracer
|
|
||||||
WaitForSingleObject(m_hProcess, 1500);
|
|
||||||
|
|
||||||
// If process is still running, terminate it
|
|
||||||
if (m_hProcess)
|
|
||||||
{
|
|
||||||
TerminateProcess(m_hProcess, 0);
|
|
||||||
m_hProcess = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void parse_hotkey(PowerToysSettings::PowerToyValues& settings)
|
|
||||||
{
|
|
||||||
auto settingsObject = settings.get_raw_json();
|
|
||||||
if (settingsObject.GetView().Size())
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
auto jsonHotkeyObject = settingsObject.GetNamedObject(JSON_KEY_PROPERTIES).GetNamedObject(JSON_KEY_HOTKEY).GetNamedObject(JSON_KEY_VALUE);
|
|
||||||
m_hotkey.win = jsonHotkeyObject.GetNamedBoolean(JSON_KEY_WIN);
|
|
||||||
m_hotkey.alt = jsonHotkeyObject.GetNamedBoolean(JSON_KEY_ALT);
|
|
||||||
m_hotkey.shift = jsonHotkeyObject.GetNamedBoolean(JSON_KEY_SHIFT);
|
|
||||||
m_hotkey.ctrl = jsonHotkeyObject.GetNamedBoolean(JSON_KEY_CTRL);
|
|
||||||
m_hotkey.key = static_cast<unsigned char>(jsonHotkeyObject.GetNamedNumber(JSON_KEY_CODE));
|
|
||||||
}
|
|
||||||
catch (...)
|
|
||||||
{
|
|
||||||
Logger::error("Failed to initialize AlwaysOnTop start shortcut");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger::info("AlwaysOnTop settings are empty");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool is_process_running()
|
|
||||||
{
|
|
||||||
return WaitForSingleObject(m_hProcess, 0) == WAIT_TIMEOUT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void init_settings()
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
// Load and parse the settings file for this PowerToy.
|
|
||||||
PowerToysSettings::PowerToyValues settings =
|
|
||||||
PowerToysSettings::PowerToyValues::load_from_settings_file(get_key());
|
|
||||||
|
|
||||||
parse_hotkey(settings);
|
|
||||||
}
|
|
||||||
catch (std::exception&)
|
|
||||||
{
|
|
||||||
Logger::warn(L"An exception occurred while loading the settings file");
|
|
||||||
// Error while loading from the settings file. Let default values stay as they are.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
std::wstring app_name;
|
|
||||||
std::wstring app_key; //contains the non localized key of the powertoy
|
|
||||||
|
|
||||||
bool m_enabled = false;
|
|
||||||
HANDLE m_hProcess = nullptr;
|
|
||||||
Hotkey m_hotkey;
|
|
||||||
|
|
||||||
// Handle to event used to pin/unpin windows
|
|
||||||
HANDLE m_hPinEvent;
|
|
||||||
HANDLE m_hTerminateEvent;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern "C" __declspec(dllexport) PowertoyModuleIface* __cdecl powertoy_create()
|
|
||||||
{
|
|
||||||
return new AlwaysOnTopModuleInterface();
|
|
||||||
}
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<packages>
|
|
||||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.240111.5" targetFramework="native" />
|
|
||||||
<package id="Microsoft.Windows.ImplementationLibrary" version="1.0.231216.1" targetFramework="native" />
|
|
||||||
</packages>
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
#include "pch.h"
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
|
||||||
#include <Unknwn.h>
|
|
||||||
#include <winrt/base.h>
|
|
||||||
#include <winrt/Windows.Foundation.h>
|
|
||||||
#include <winrt/Windows.Foundation.Collections.h>
|
|
||||||
#include <wil\common.h>
|
|
||||||
#include <wil\result.h>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
//{{NO_DEPENDENCIES}}
|
|
||||||
// Microsoft Visual C++ generated include file.
|
|
||||||
// Used by AlwaysOnTopModuleInterface.rc
|
|
||||||
|
|
||||||
//////////////////////////////
|
|
||||||
// Non-localizable
|
|
||||||
|
|
||||||
#define FILE_DESCRIPTION "PowerToys AlwaysOnTop Module"
|
|
||||||
#define INTERNAL_NAME "PowerToys.AlwaysOnTopModuleInterface"
|
|
||||||
#define ORIGINAL_FILENAME "PowerToys.AlwaysOnTopModuleInterface.dll"
|
|
||||||
|
|
||||||
// Non-localizable
|
|
||||||
//////////////////////////////
|
|
||||||
Binary file not shown.
@@ -0,0 +1,32 @@
|
|||||||
|
// 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.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||||
|
|
||||||
|
namespace Settings.UI.Library
|
||||||
|
{
|
||||||
|
public class LastVersionRunSettings : ISettingsConfig
|
||||||
|
{
|
||||||
|
[JsonPropertyName("last_version")]
|
||||||
|
public string LastVersion { get; set; }
|
||||||
|
|
||||||
|
public string GetModuleName()
|
||||||
|
{
|
||||||
|
return "LastVersionRun";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ToJsonString()
|
||||||
|
{
|
||||||
|
return JsonSerializer.Serialize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UpgradeSettingsConfiguration()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
32
src/settings-ui/Settings.UI.Library/OOBESettings.cs
Normal file
32
src/settings-ui/Settings.UI.Library/OOBESettings.cs
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
// 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.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
|
||||||
|
|
||||||
|
namespace Settings.UI.Library
|
||||||
|
{
|
||||||
|
public class OOBESettings : ISettingsConfig
|
||||||
|
{
|
||||||
|
[JsonPropertyName("openedAtFirstLaunch")]
|
||||||
|
public bool OpenedAtFirstLaunch { get; set; }
|
||||||
|
|
||||||
|
public string GetModuleName()
|
||||||
|
{
|
||||||
|
return "OOBE";
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ToJsonString()
|
||||||
|
{
|
||||||
|
return JsonSerializer.Serialize(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool UpgradeSettingsConfiguration()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
|
<!-- See https://learn.microsoft.com/windows/apps/develop/platform/csharp-winrt/net-projection-from-cppwinrt-component for more info -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<CsWinRTIncludes>PowerToys.GPOWrapper;PowerToys.ZoomItSettingsInterop</CsWinRTIncludes>
|
<CsWinRTIncludes>PowerToys.ZoomItSettingsInterop</CsWinRTIncludes>
|
||||||
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
|
<CsWinRTGeneratedFilesDir>$(OutDir)</CsWinRTGeneratedFilesDir>
|
||||||
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
<ErrorOnDuplicatePublishOutputFiles>false</ErrorOnDuplicatePublishOutputFiles>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@@ -113,7 +113,7 @@
|
|||||||
<ProjectReference Include="..\..\common\Common.Search\Common.Search.csproj" />
|
<ProjectReference Include="..\..\common\Common.Search\Common.Search.csproj" />
|
||||||
<ProjectReference Include="..\..\common\Common.UI\Common.UI.csproj" />
|
<ProjectReference Include="..\..\common\Common.UI\Common.UI.csproj" />
|
||||||
<ProjectReference Include="..\..\common\AllExperiments\AllExperiments.csproj" />
|
<ProjectReference Include="..\..\common\AllExperiments\AllExperiments.csproj" />
|
||||||
<ProjectReference Include="..\..\common\GPOWrapper\GPOWrapper.vcxproj" />
|
<ProjectReference Include="..\..\common\GPOWrapperProjection\GPOWrapperProjection.csproj" />
|
||||||
<ProjectReference Include="..\..\common\interop\PowerToys.Interop.vcxproj" />
|
<ProjectReference Include="..\..\common\interop\PowerToys.Interop.vcxproj" />
|
||||||
<ProjectReference Include="..\..\modules\ZoomIt\ZoomItSettingsInterop\ZoomItSettingsInterop.vcxproj" />
|
<ProjectReference Include="..\..\modules\ZoomIt\ZoomItSettingsInterop\ZoomItSettingsInterop.vcxproj" />
|
||||||
<ProjectReference Include="..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
<ProjectReference Include="..\..\common\ManagedCommon\ManagedCommon.csproj" />
|
||||||
|
|||||||
Reference in New Issue
Block a user