Skip to content

Commit 58d3408

Browse files
[GPO]Add policy to define the run at startup setting (#37385)
* [GPO]Add policy to define the run at startup setting * Use message for single setting managed by policy instead
1 parent 0c7a1dd commit 58d3408

File tree

10 files changed

+88
-4
lines changed

10 files changed

+88
-4
lines changed

src/common/GPOWrapper/GPOWrapper.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -232,4 +232,8 @@ namespace winrt::PowerToys::GPOWrapper::implementation
232232
{
233233
return static_cast<GpoRuleConfigured>(powertoys_gpo::getAllowDataDiagnosticsValue());
234234
}
235+
GpoRuleConfigured GPOWrapper::GetConfiguredRunAtStartupValue()
236+
{
237+
return static_cast<GpoRuleConfigured>(powertoys_gpo::getConfiguredRunAtStartupValue());
238+
}
235239
}

src/common/GPOWrapper/GPOWrapper.h

+1
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ namespace winrt::PowerToys::GPOWrapper::implementation
6363
static winrt::hstring GPOWrapper::GetConfiguredMwbPolicyDefinedIpMappingRules();
6464
static GpoRuleConfigured GetConfiguredNewPlusHideTemplateFilenameExtensionValue();
6565
static GpoRuleConfigured GetAllowDataDiagnosticsValue();
66+
static GpoRuleConfigured GetConfiguredRunAtStartupValue();
6667
};
6768
}
6869

src/common/GPOWrapper/GPOWrapper.idl

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ namespace PowerToys
6767
static String GetConfiguredMwbPolicyDefinedIpMappingRules();
6868
static GpoRuleConfigured GetConfiguredNewPlusHideTemplateFilenameExtensionValue();
6969
static GpoRuleConfigured GetAllowDataDiagnosticsValue();
70+
static GpoRuleConfigured GetConfiguredRunAtStartupValue();
7071
}
7172
}
7273
}

src/common/utils/gpo.h

+6
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ namespace powertoys_gpo {
7373
// The registry value names for other PowerToys policies.
7474
const std::wstring POLICY_ALLOW_EXPERIMENTATION = L"AllowExperimentation";
7575
const std::wstring POLICY_ALLOW_DATA_DIAGNOSTICS = L"AllowDataDiagnostics";
76+
const std::wstring POLICY_CONFIGURE_RUN_AT_STARTUP = L"ConfigureRunAtStartup";
7677
const std::wstring POLICY_CONFIGURE_ENABLED_POWER_LAUNCHER_ALL_PLUGINS = L"PowerLauncherAllPluginsEnabledState";
7778
const std::wstring POLICY_ALLOW_ADVANCED_PASTE_ONLINE_AI_MODELS = L"AllowPowerToysAdvancedPasteOnlineAIModels";
7879
const std::wstring POLICY_MWB_CLIPBOARD_SHARING_ENABLED = L"MwbClipboardSharingEnabled";
@@ -494,6 +495,11 @@ namespace powertoys_gpo {
494495
return getConfiguredValue(POLICY_ALLOW_DATA_DIAGNOSTICS);
495496
}
496497

498+
inline gpo_rule_configured_t getConfiguredRunAtStartupValue()
499+
{
500+
return getConfiguredValue(POLICY_CONFIGURE_RUN_AT_STARTUP);
501+
}
502+
497503
inline gpo_rule_configured_t getRunPluginEnabledValue(std::string pluginID)
498504
{
499505
if (pluginID == "" || pluginID == " ")

src/gpo/assets/PowerToys.admx

+10
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,16 @@
536536
<decimal value="0" />
537537
</disabledValue>
538538
</policy>
539+
<policy name="ConfigureRunAtStartup" class="Both" displayName="$(string.ConfigureRunAtStartup)" explainText="$(string.ConfigureRunAtStartupDescription)" key="Software\Policies\PowerToys" valueName="ConfigureRunAtStartup">
540+
<parentCategory ref="GeneralSettings" />
541+
<supportedOn ref="SUPPORTED_POWERTOYS_0_89_0" />
542+
<enabledValue>
543+
<decimal value="1" />
544+
</enabledValue>
545+
<disabledValue>
546+
<decimal value="0" />
547+
</disabledValue>
548+
</policy>
539549
<policy name="PowerToysRunAllPluginsEnabledState" class="Both" displayName="$(string.PowerToysRunAllPluginsEnabledState)" explainText="$(string.PowerToysRunAllPluginsEnabledStateDescription)" key="Software\Policies\PowerToys" valueName="PowerLauncherAllPluginsEnabledState">
540550
<parentCategory ref="PowerToysRun" />
541551
<supportedOn ref="SUPPORTED_POWERTOYS_0_75_0" />

src/gpo/assets/en-US/PowerToys.adml

+11
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,16 @@ If this setting is disabled, experimentation is not allowed.
112112
If this setting is enabled or not configured, the user can control diagnostic data sending in the PowerToys settings menu.
113113

114114
If this setting is disabled, diagnostic data sending is not allowed.
115+
</string>
116+
<string id="ConfigureRunAtStartupDescription">This policy configures the "run at startup" setting of PowerToys.
117+
118+
If you enable this setting, the "run at startup" setting will be always enabled and the user won't be able to disable it.
119+
120+
If you disable this setting, the "run at startup" setting will be always disabled and the user won't be able to enable it.
121+
122+
If you don't configure this setting, users are able to enable or disable "run at startup" at will.
123+
124+
Note: This only controls the PowerToys method that creates a scheduled task to start PowerToys at login. It doesn't control other custom auto-start methods that the user might try to use outside of PowerToys or manually creating/deleting a scheduled task.
115125
</string>
116126
<string id="PowerToysRunAllPluginsEnabledStateDescription">This policy configures the enabled state for all PowerToys Run plugins. All plugins will have the same state.
117127

@@ -279,6 +289,7 @@ If you don't configure this policy, the user takes control over the setting and
279289
<string id="MwbPolicyDefinedIpMappingRules">Predefined IP Address mapping rules</string>
280290
<string id="NewPlusHideTemplateFilenameExtension">Hide template filename extension</string>
281291
<string id="AllowDiagnosticData">Allow sending diagnostic data</string>
292+
<string id="ConfigureRunAtStartup">Configure the run at startup setting</string>
282293
</stringTable>
283294

284295
<presentationTable>

src/runner/general_settings.cpp

+16-2
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,21 @@ void apply_general_settings(const json::JsonObject& general_configs, bool save)
112112

113113
enable_experimentation = general_configs.GetNamedBoolean(L"enable_experimentation", true);
114114

115+
// apply_general_settings is called by the runner's WinMain, so we can just force the run at startup gpo rule here.
116+
auto gpo_run_as_startup = powertoys_gpo::getConfiguredRunAtStartupValue();
117+
115118
if (json::has(general_configs, L"startup", json::JsonValueType::Boolean))
116119
{
117-
const bool startup = general_configs.GetNamedBoolean(L"startup");
120+
bool startup = general_configs.GetNamedBoolean(L"startup");
121+
122+
if (gpo_run_as_startup == powertoys_gpo::gpo_rule_configured_enabled)
123+
{
124+
startup = true;
125+
}
126+
else if (gpo_run_as_startup == powertoys_gpo::gpo_rule_configured_disabled)
127+
{
128+
startup = false;
129+
}
118130

119131
if (startup)
120132
{
@@ -147,7 +159,9 @@ void apply_general_settings(const json::JsonObject& general_configs, bool save)
147159
else
148160
{
149161
delete_auto_start_task_for_this_user();
150-
create_auto_start_task_for_this_user(run_as_elevated);
162+
if (gpo_run_as_startup == powertoys_gpo::gpo_rule_configured_enabled || gpo_run_as_startup == powertoys_gpo::gpo_rule_configured_not_configured) {
163+
create_auto_start_task_for_this_user(run_as_elevated);
164+
}
151165
}
152166

153167
if (json::has(general_configs, L"enabled"))

src/settings-ui/Settings.UI/SettingsXAML/Views/GeneralPage.xaml

+13-1
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,21 @@
263263
</ComboBox>
264264
</tkcontrols:SettingsCard>
265265

266-
<tkcontrols:SettingsCard x:Uid="GeneralPage_RunAtStartUp">
266+
<tkcontrols:SettingsCard x:Uid="GeneralPage_RunAtStartUp" IsEnabled="{x:Bind ViewModel.IsRunAtStartupGPOManaged, Mode=OneWay, Converter={StaticResource BoolNegationConverter}}">
267267
<ToggleSwitch x:Uid="ToggleSwitch" IsOn="{x:Bind ViewModel.Startup, Mode=TwoWay}" />
268268
</tkcontrols:SettingsCard>
269+
<InfoBar
270+
x:Uid="GPO_SettingIsManaged"
271+
BorderThickness="0"
272+
CornerRadius="0"
273+
IsClosable="False"
274+
IsOpen="{x:Bind ViewModel.IsRunAtStartupGPOManaged, Mode=OneWay}"
275+
IsTabStop="{x:Bind ViewModel.IsRunAtStartupGPOManaged, Mode=OneWay}"
276+
Severity="Informational">
277+
<InfoBar.IconSource>
278+
<FontIconSource FontFamily="{StaticResource SymbolThemeFontFamily}" Glyph="&#xE72E;" />
279+
</InfoBar.IconSource>
280+
</InfoBar>
269281
</controls:SettingsGroup>
270282

271283
<controls:SettingsGroup x:Uid="General_SettingsBackupAndRestoreTitle" Visibility="Visible">

src/settings-ui/Settings.UI/ViewModels/GeneralViewModel.cs

+25-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,18 @@ public GeneralViewModel(ISettingsRepository<GeneralSettings> settingsRepository,
121121

122122
_isDevBuild = Helper.GetProductVersion() == "v0.0.1";
123123

124-
_startup = GeneralSettingsConfig.Startup;
124+
_runAtStartupGpoRuleConfiguration = GPOWrapper.GetConfiguredRunAtStartupValue();
125+
if (_runAtStartupGpoRuleConfiguration == GpoRuleConfigured.Disabled || _runAtStartupGpoRuleConfiguration == GpoRuleConfigured.Enabled)
126+
{
127+
// Get the enabled state from GPO.
128+
_runAtStartupIsGPOConfigured = true;
129+
_startup = _runAtStartupGpoRuleConfiguration == GpoRuleConfigured.Enabled;
130+
}
131+
else
132+
{
133+
_startup = GeneralSettingsConfig.Startup;
134+
}
135+
125136
_showNewUpdatesToastNotification = GeneralSettingsConfig.ShowNewUpdatesToastNotification;
126137
_autoDownloadUpdates = GeneralSettingsConfig.AutoDownloadUpdates;
127138
_showWhatsNewAfterUpdates = GeneralSettingsConfig.ShowWhatsNewAfterUpdates;
@@ -204,6 +215,8 @@ public GeneralViewModel(ISettingsRepository<GeneralSettings> settingsRepository,
204215

205216
private static bool _isDevBuild;
206217
private bool _startup;
218+
private GpoRuleConfigured _runAtStartupGpoRuleConfiguration;
219+
private bool _runAtStartupIsGPOConfigured;
207220
private bool _isElevated;
208221
private bool _runElevated;
209222
private bool _isAdmin;
@@ -251,6 +264,12 @@ public bool Startup
251264

252265
set
253266
{
267+
if (_runAtStartupIsGPOConfigured)
268+
{
269+
// If it's GPO configured, shouldn't be able to change this state.
270+
return;
271+
}
272+
254273
if (_startup != value)
255274
{
256275
_startup = value;
@@ -524,6 +543,11 @@ public bool IsDataDiagnosticsGPOManaged
524543
get => _enableDataDiagnosticsIsGpoDisallowed;
525544
}
526545

546+
public bool IsRunAtStartupGPOManaged
547+
{
548+
get => _runAtStartupIsGPOConfigured;
549+
}
550+
527551
public string SettingsBackupAndRestoreDir
528552
{
529553
get

tools/BugReportTool/BugReportTool/ReportGPOValues.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -95,4 +95,5 @@ void ReportGPOValues(const std::filesystem::path &tmpDir)
9595
report << "getConfiguredNewPlusEnabledValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredNewPlusEnabledValue()) << std::endl;
9696
report << "getConfiguredNewPlusHideTemplateFilenameExtensionValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredNewPlusHideTemplateFilenameExtensionValue()) << std::endl;
9797
report << "getAllowDataDiagnosticsValue: " << gpo_rule_configured_to_string(powertoys_gpo::getAllowDataDiagnosticsValue()) << std::endl;
98+
report << "getConfiguredRunAtStartupValue: " << gpo_rule_configured_to_string(powertoys_gpo::getConfiguredRunAtStartupValue()) << std::endl;
9899
}

0 commit comments

Comments
 (0)