diff --git a/.github/actions/spell-check/expect.txt b/.github/actions/spell-check/expect.txt index 2c780296c4..9974ab63ea 100644 --- a/.github/actions/spell-check/expect.txt +++ b/.github/actions/spell-check/expect.txt @@ -283,7 +283,6 @@ CLIPCHILDREN CLIPSIBLINGS Cloneable clrcall -clrcompression Cls CLSCTX clsid @@ -427,7 +426,6 @@ DCOM dcommon dcomp dcompi -DCompiler DComposition DCR DCs @@ -581,7 +579,6 @@ EFDD EFE EFFEFC EFile -egfile ekus emmintrin Emoji @@ -645,7 +642,6 @@ FAF FAFD fancymouse fancyzone -fancyzones FANCYZONESDRAWLAYOUTTEST FANCYZONESEDITOR Farbraum @@ -746,6 +742,7 @@ GNumber google gpedit gpo +GPOCA GPT gpu graphql @@ -893,7 +890,6 @@ IMAGERESIZEREXT imageresizerinput imageresizersettings imagingdevices -Imc ime imeutil inetcpl @@ -1449,7 +1445,6 @@ pinfo pinvoke pipename PKBDLLHOOKSTRUCT -Pkcs PKEY plib PLK @@ -1597,9 +1592,9 @@ REGFILTERPINS REGISTERCLASSFAILED REGISTRYHEADER registrypath -registryroot registrypreview REGISTRYPREVIEWEXT +registryroot regkey REGPINTYPES regroot @@ -1851,7 +1846,6 @@ stdcpplatest STDMETHODCALLTYPE STDMETHODIMP stefan -stefansjfw Stereolithography STGM STGMEDIUM @@ -2211,7 +2205,6 @@ wox wparam wpf wpfdepsjsonpath -wpfgfx wpftmp wpr wprp diff --git a/doc/gpo/README.md b/doc/gpo/README.md index 134679f147..351ed5a376 100644 --- a/doc/gpo/README.md +++ b/doc/gpo/README.md @@ -44,6 +44,15 @@ If this setting is not configured, experimentation is allowed. ### Installer and Updates +#### Disable per-user installation + +This policy configures whether PowerToys per-user installation is allowed or not. + +If enabled, per-user installation is not allowed. + +If disabled or not configured, per-user installation is allowed. + +You can set this policy only as Computer policy. #### Disable automatic downloads This policy configures whether automatic downloads of available updates are disabled or not. (On metered connections updates are never downloaded.) diff --git a/installer/PowerToysSetup/Product.wxs b/installer/PowerToysSetup/Product.wxs index 6569f77162..8ed3729a45 100644 --- a/installer/PowerToysSetup/Product.wxs +++ b/installer/PowerToysSetup/Product.wxs @@ -148,6 +148,9 @@ NOT Installed and CREATESCHEDULEDTASK = 1 + + NOT Installed + NOT Installed @@ -413,6 +416,13 @@ DllEntry="UnRegisterContextMenuPackagesCA" /> + + diff --git a/installer/PowerToysSetupCustomActions/CustomAction.cpp b/installer/PowerToysSetupCustomActions/CustomAction.cpp index 52a22a96c8..e3faecded6 100644 --- a/installer/PowerToysSetupCustomActions/CustomAction.cpp +++ b/installer/PowerToysSetupCustomActions/CustomAction.cpp @@ -6,6 +6,7 @@ #include #include "../../src/common/logger/logger.h" +#include "../../src/common/utils/gpo.h" #include "../../src/common/utils/MsiUtils.h" #include "../../src/common/utils/modulesRegistry.h" #include "../../src/common/updating/installer.h" @@ -50,6 +51,33 @@ HRESULT getInstallFolder(MSIHANDLE hInstall, std::wstring& installationDir) LExit: return hr; } + +UINT __stdcall CheckGPOCA(MSIHANDLE hInstall) +{ + HRESULT hr = S_OK; + + hr = WcaInitialize(hInstall, "CheckGPOCA"); + ExitOnFailure(hr, "Failed to initialize"); + + LPWSTR currentScope = nullptr; + hr = WcaGetProperty(L"InstallScope", ¤tScope); + + if(std::wstring{ currentScope } == L"perUser") + { + if (powertoys_gpo::getDisablePerUserInstallationValue() == powertoys_gpo::gpo_rule_configured_enabled) + { + PMSIHANDLE hRecord = MsiCreateRecord(0); + MsiRecordSetString(hRecord, 0, TEXT("The system administrator has disabled per-user installation.")); + MsiProcessMessage(hInstall, static_cast(INSTALLMESSAGE_ERROR + MB_OK), hRecord); + hr = E_ABORT; + } + } + +LExit: + UINT er = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE; + return WcaFinalize(er); +} + UINT __stdcall ApplyModulesRegistryChangeSetsCA(MSIHANDLE hInstall) { HRESULT hr = S_OK; diff --git a/installer/PowerToysSetupCustomActions/CustomAction.def b/installer/PowerToysSetupCustomActions/CustomAction.def index 27d59b2fda..21f2547052 100644 --- a/installer/PowerToysSetupCustomActions/CustomAction.def +++ b/installer/PowerToysSetupCustomActions/CustomAction.def @@ -1,6 +1,7 @@ LIBRARY "PowerToysSetupCustomActions" EXPORTS + CheckGPOCA ApplyModulesRegistryChangeSetsCA CreateScheduledTaskCA CreateWinAppSDKHardlinksCA diff --git a/src/common/utils/gpo.h b/src/common/utils/gpo.h index 31563a2075..e105749812 100644 --- a/src/common/utils/gpo.h +++ b/src/common/utils/gpo.h @@ -51,6 +51,7 @@ namespace powertoys_gpo { const std::wstring POLICY_CONFIGURE_ENABLED_REGISTRY_PREVIEW = L"ConfigureEnabledUtilityRegistryPreview"; // The registry value names for PowerToys installer and update policies. + const std::wstring POLICY_DISABLE_PER_USER_INSTALLATION = L"PerUserInstallationDisabled"; const std::wstring POLICY_DISABLE_AUTOMATIC_UPDATE_DOWNLOAD = L"AutomaticUpdateDownloadDisabled"; const std::wstring POLICY_SUSPEND_NEW_UPDATE_TOAST = L"SuspendNewUpdateAvailableToast"; const std::wstring POLICY_DISABLE_PERIODIC_UPDATE_CHECK = L"PeriodicUpdateCheckDisabled"; @@ -260,6 +261,12 @@ namespace powertoys_gpo { { return getConfiguredValue(POLICY_CONFIGURE_ENABLED_REGISTRY_PREVIEW); } + + inline gpo_rule_configured_t getDisablePerUserInstallationValue() + { + return getConfiguredValue(POLICY_DISABLE_PER_USER_INSTALLATION); + } + inline gpo_rule_configured_t getDisableAutomaticUpdateDownloadValue() { return getConfiguredValue(POLICY_DISABLE_AUTOMATIC_UPDATE_DOWNLOAD); diff --git a/src/gpo/assets/PowerToys.admx b/src/gpo/assets/PowerToys.admx index e3f44a5118..c1b618425b 100644 --- a/src/gpo/assets/PowerToys.admx +++ b/src/gpo/assets/PowerToys.admx @@ -319,7 +319,17 @@ - + + + + + + + + + + + @@ -329,7 +339,7 @@ - + diff --git a/src/gpo/assets/en-US/PowerToys.adml b/src/gpo/assets/en-US/PowerToys.adml index 915d61f6c9..a551c8b4ba 100644 --- a/src/gpo/assets/en-US/PowerToys.adml +++ b/src/gpo/assets/en-US/PowerToys.adml @@ -30,6 +30,12 @@ If you enable this setting, the utility will be always enabled and the user won' If you disable this setting, the utility will be always disabled and the user won't be able to enable it. If you don't configure this setting, users are able to disable or enable the utility. + + This policy configures whether per-user PowerToys installation is allowed or not. + +If enabled, per-user installation is not allowed. + +If disabled or not configured, per-user installation is allowed. This policy configures whether automatic downloads of available updates are disabled or not. (On metered connections updates are never downloaded.) @@ -87,9 +93,10 @@ If this setting is disabled, experimentation is not allowed. Shortcut Guide: Configure enabled state Text Extractor: Configure enabled state Video Conference Mute: Configure enabled state - Disable automatic downloads - Suspend Action Center notification for new updates - Disable automatic update checks + Disable per-user installation + Disable automatic downloads + Suspend Action Center notification for new updates + Disable automatic update checks Allow Experimentation