[GPO] Add policies for configuring utilities enabled states (#21411)

* Add GPOWrapper headers and C++/WinRT library

* Check GPO before starting utilities

* Show message on GPO having disabled preview panes.

* Don't generate thumbnails if GPO disabled

* Fix FancyZonesEditor unable to recognize GPOWrapper

* Move settings view models to the settings project

* Use GPO to block enabling utilities in Settings

* Hide context menu entries when gpo disables utilities

* Apply gpo policies when enabling PowerToys on runner

* Add version and metadata to dll

* Add GPOWrapper to the installer

* Fix MSBuild errors on WPF apps by using Projection

* Signing

* Add gpo files and publish them

* Add GPO policies to the bug report tool

* Add some documentation for using GPO

* Mention support to actual lowest supported version of Windows

* Move PowerToys to the root of administrative templates tree

* Save policies on Software\Policies\PowerToys

* Support both machine and user scopes

* Fix documentation to reference computer and user scopes

* Mention incompatibility with outlook in gpo

* Set a better folder structure for gpo assets

* Move PDF Handler warning to the description

* Update doc/gpo/README.md

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>

* Add actual minimum version of PowerToys to gpo files

* Fix identation

* Remove GPOWrapper Readme

* Add Active Directory instructions to doc

Co-authored-by: Heiko <61519853+htcfreek@users.noreply.github.com>
This commit is contained in:
Jaime Bernardo
2022-10-26 14:02:31 +01:00
committed by GitHub
parent 1ff5fa8794
commit a63288009a
182 changed files with 3257 additions and 449 deletions

View File

@@ -0,0 +1,185 @@
// 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.Globalization;
using System.Text.Json;
using System.Timers;
using global::PowerToys.GPOWrapper;
using Microsoft.PowerToys.Settings.UI.Library;
using Microsoft.PowerToys.Settings.UI.Library.Helpers;
using Microsoft.PowerToys.Settings.UI.Library.Interfaces;
namespace Microsoft.PowerToys.Settings.UI.ViewModels
{
public class PowerOcrViewModel : Observable, IDisposable
{
private bool disposedValue;
// Delay saving of settings in order to avoid calling save multiple times and hitting file in use exception. If there is no other request to save settings in given interval, we proceed to save it, otherwise we schedule saving it after this interval
private const int SaveSettingsDelayInMs = 500;
private GeneralSettings GeneralSettingsConfig { get; set; }
private readonly ISettingsUtils _settingsUtils;
private readonly object _delayedActionLock = new object();
private readonly PowerOcrSettings _powerOcrSettings;
private Timer _delayedTimer;
private GpoRuleConfigured _enabledGpoRuleConfiguration;
private bool _enabledStateIsGPOConfigured;
private bool _isEnabled;
private Func<string, int> SendConfigMSG { get; }
public PowerOcrViewModel(
ISettingsUtils settingsUtils,
ISettingsRepository<GeneralSettings> settingsRepository,
ISettingsRepository<PowerOcrSettings> powerOcrsettingsRepository,
Func<string, int> ipcMSGCallBackFunc)
{
// To obtain the general settings configurations of PowerToys Settings.
if (settingsRepository == null)
{
throw new ArgumentNullException(nameof(settingsRepository));
}
GeneralSettingsConfig = settingsRepository.SettingsConfig;
// To obtain the settings configurations of Fancy zones.
if (settingsRepository == null)
{
throw new ArgumentNullException(nameof(settingsRepository));
}
_settingsUtils = settingsUtils ?? throw new ArgumentNullException(nameof(settingsUtils));
if (powerOcrsettingsRepository == null)
{
throw new ArgumentNullException(nameof(powerOcrsettingsRepository));
}
_powerOcrSettings = powerOcrsettingsRepository.SettingsConfig;
_enabledGpoRuleConfiguration = GPOWrapper.GetConfiguredTextExtractorEnabledValue();
if (_enabledGpoRuleConfiguration == GpoRuleConfigured.Disabled || _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled)
{
// Get the enabled state from GPO.
_enabledStateIsGPOConfigured = true;
_isEnabled = _enabledGpoRuleConfiguration == GpoRuleConfigured.Enabled;
}
else
{
_isEnabled = GeneralSettingsConfig.Enabled.PowerOCR;
}
// set the callback functions value to hangle outgoing IPC message.
SendConfigMSG = ipcMSGCallBackFunc;
_delayedTimer = new Timer();
_delayedTimer.Interval = SaveSettingsDelayInMs;
_delayedTimer.Elapsed += DelayedTimer_Tick;
_delayedTimer.AutoReset = false;
}
public bool IsEnabled
{
get => _isEnabled;
set
{
if (_enabledStateIsGPOConfigured)
{
// If it's GPO configured, shouldn't be able to change this state.
return;
}
if (_isEnabled != value)
{
_isEnabled = value;
OnPropertyChanged(nameof(IsEnabled));
// Set the status of PowerOCR in the general settings
GeneralSettingsConfig.Enabled.PowerOCR = value;
var outgoing = new OutGoingGeneralSettings(GeneralSettingsConfig);
SendConfigMSG(outgoing.ToString());
}
}
}
public bool IsEnabledGpoConfigured
{
get => _enabledStateIsGPOConfigured;
}
public HotkeySettings ActivationShortcut
{
get => _powerOcrSettings.Properties.ActivationShortcut;
set
{
if (_powerOcrSettings.Properties.ActivationShortcut != value)
{
_powerOcrSettings.Properties.ActivationShortcut = value;
OnPropertyChanged(nameof(ActivationShortcut));
_settingsUtils.SaveSettings(_powerOcrSettings.ToJsonString(), PowerOcrSettings.ModuleName);
NotifySettingsChanged();
}
}
}
private void ScheduleSavingOfSettings()
{
lock (_delayedActionLock)
{
if (_delayedTimer.Enabled)
{
_delayedTimer.Stop();
}
_delayedTimer.Start();
}
}
private void DelayedTimer_Tick(object sender, EventArgs e)
{
lock (_delayedActionLock)
{
_delayedTimer.Stop();
NotifySettingsChanged();
}
}
private void NotifySettingsChanged()
{
// Using InvariantCulture as this is an IPC message
SendConfigMSG(
string.Format(
CultureInfo.InvariantCulture,
"{{ \"powertoys\": {{ \"{0}\": {1} }} }}",
PowerOcrSettings.ModuleName,
JsonSerializer.Serialize(_powerOcrSettings)));
}
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
_delayedTimer.Dispose();
}
disposedValue = true;
}
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
}
}