mirror of
https://github.com/microsoft/PowerToys.git
synced 2026-04-05 02:36:19 +02:00
[Settings Tests] Migrate General Settings tests (#5753)
* added MSTest project * migrated general settings tests * enabled settings tests run in the build pipeline * added tests * move relay command class to separate file * added a foldername parameter for general settings view model
This commit is contained in:
@@ -0,0 +1,27 @@
|
||||
// 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.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib.Helpers
|
||||
{
|
||||
public class Observable : INotifyPropertyChanged
|
||||
{
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected void Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
|
||||
{
|
||||
if (Equals(storage, value))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
storage = value;
|
||||
OnPropertyChanged(propertyName);
|
||||
}
|
||||
|
||||
protected void OnPropertyChanged(string propertyName) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels.Commands
|
||||
{
|
||||
public class ButtonClickCommand : ICommand
|
||||
{
|
||||
private readonly Action _execute;
|
||||
|
||||
public ButtonClickCommand(Action execute)
|
||||
{
|
||||
this._execute = execute;
|
||||
}
|
||||
|
||||
// Occurs when changes occur that affect whether or not the command should execute.
|
||||
public event EventHandler CanExecuteChanged;
|
||||
|
||||
// Defines the method that determines whether the command can execute in its current state.
|
||||
public bool CanExecute(object parameter)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Defines the method to be called when the command is invoked.
|
||||
public void Execute(object parameter)
|
||||
{
|
||||
_execute();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels.Commands
|
||||
{
|
||||
public class RelayCommand : ICommand
|
||||
{
|
||||
private readonly Action _execute;
|
||||
private readonly Func<bool> _canExecute;
|
||||
|
||||
public event EventHandler CanExecuteChanged;
|
||||
|
||||
public RelayCommand(Action execute)
|
||||
: this(execute, null)
|
||||
{
|
||||
}
|
||||
|
||||
public RelayCommand(Action execute, Func<bool> canExecute)
|
||||
{
|
||||
_execute = execute ?? throw new ArgumentNullException(nameof(execute));
|
||||
_canExecute = canExecute;
|
||||
}
|
||||
|
||||
public bool CanExecute(object parameter) => _canExecute == null || _canExecute();
|
||||
|
||||
public void Execute(object parameter) => _execute();
|
||||
|
||||
public void OnCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// 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.Windows.Input;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels.Commands
|
||||
{
|
||||
|
||||
public class RelayCommand<T> : ICommand
|
||||
{
|
||||
private readonly Action<T> execute;
|
||||
|
||||
private readonly Func<T, bool> canExecute;
|
||||
|
||||
public event EventHandler CanExecuteChanged;
|
||||
|
||||
public RelayCommand(Action<T> execute)
|
||||
: this(execute, null)
|
||||
{
|
||||
}
|
||||
|
||||
public RelayCommand(Action<T> execute, Func<T, bool> canExecute)
|
||||
{
|
||||
this.execute = execute ?? throw new ArgumentNullException(nameof(execute));
|
||||
this.canExecute = canExecute;
|
||||
}
|
||||
|
||||
public bool CanExecute(object parameter) => canExecute == null || canExecute((T)parameter);
|
||||
|
||||
public void Execute(object parameter) => execute((T)parameter);
|
||||
|
||||
public void OnCanExecuteChanged() => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
}
|
||||
@@ -5,15 +5,12 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Microsoft.PowerToys.Settings.UI.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.Helpers;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.Utilities;
|
||||
using Microsoft.PowerToys.Settings.UI.ViewModels.Commands;
|
||||
using Microsoft.PowerToys.Settings.UI.Views;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.UI.Xaml;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.ViewModels.Commands;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
namespace Microsoft.PowerToys.Settings.UI.Lib.ViewModels
|
||||
{
|
||||
public class GeneralViewModel : Observable
|
||||
{
|
||||
@@ -23,26 +20,25 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
|
||||
public ButtonClickCommand RestartElevatedButtonEventHandler { get; set; }
|
||||
|
||||
private ResourceLoader loader = ResourceLoader.GetForViewIndependentUse();
|
||||
|
||||
public string RunningAsUserDefaultText { get; private set; }
|
||||
public Func<string, int> UpdateUIThemeCallBack { get; }
|
||||
|
||||
public string RunningAsAdminDefaultText { get; private set; }
|
||||
public Func<string, int> SendConfigMSG { get; }
|
||||
|
||||
private bool _packaged = false;
|
||||
private bool _startup = false;
|
||||
private bool _isElevated = false;
|
||||
private bool _runElevated = false;
|
||||
private bool _isAdmin = false;
|
||||
private bool _isDarkThemeRadioButtonChecked = false;
|
||||
private bool _isLightThemeRadioButtonChecked = false;
|
||||
private bool _isSystemThemeRadioButtonChecked = false;
|
||||
private bool _autoDownloadUpdates = false;
|
||||
public Func<string, int> SendRestartAsAdminConfigMSG { get; }
|
||||
|
||||
public GeneralViewModel()
|
||||
public Func<string, int> SendCheckForUpdatesConfigMSG { get; }
|
||||
|
||||
public readonly string RunningAsUserDefaultText;
|
||||
|
||||
public readonly string RunningAsAdminDefaultText;
|
||||
|
||||
public string SettingsConfigFileFolder = string.Empty;
|
||||
|
||||
public GeneralViewModel(string runAsAdminText, string runAsUserText, bool isElevated, bool isAdmin, Func<string, int> updateTheme, Func<string, int> ipcMSGCallBackFunc, Func<string, int> ipcMSGRestartAsAdminMSGCallBackFunc, Func<string, int> ipcMSGCheckForUpdatesCallBackFunc, string configFileSubfolder = "")
|
||||
{
|
||||
CheckFoUpdatesEventHandler = new ButtonClickCommand(CheckForUpdates_Click);
|
||||
RestartElevatedButtonEventHandler = new ButtonClickCommand(Restart_Elevated);
|
||||
this.CheckFoUpdatesEventHandler = new ButtonClickCommand(CheckForUpdates_Click);
|
||||
this.RestartElevatedButtonEventHandler = new ButtonClickCommand(Restart_Elevated);
|
||||
|
||||
try
|
||||
{
|
||||
@@ -66,54 +62,52 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
SettingsUtils.SaveSettings(GeneralSettingsConfigs.ToJsonString(), string.Empty);
|
||||
}
|
||||
|
||||
// set the callback functions value to hangle outgoing IPC message.
|
||||
SendConfigMSG = ipcMSGCallBackFunc;
|
||||
SendCheckForUpdatesConfigMSG = ipcMSGCheckForUpdatesCallBackFunc;
|
||||
SendRestartAsAdminConfigMSG = ipcMSGRestartAsAdminMSGCallBackFunc;
|
||||
|
||||
// set the callback function value to update the UI theme.
|
||||
UpdateUIThemeCallBack = updateTheme;
|
||||
UpdateUIThemeCallBack(GeneralSettingsConfigs.Theme.ToLower());
|
||||
|
||||
// Update Settings file folder:
|
||||
SettingsConfigFileFolder = configFileSubfolder;
|
||||
|
||||
switch (GeneralSettingsConfigs.Theme.ToLower())
|
||||
{
|
||||
case "light":
|
||||
_isLightThemeRadioButtonChecked = true;
|
||||
try
|
||||
{
|
||||
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Light;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
break;
|
||||
case "dark":
|
||||
_isDarkThemeRadioButtonChecked = true;
|
||||
try
|
||||
{
|
||||
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Dark;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
break;
|
||||
case "system":
|
||||
_isSystemThemeRadioButtonChecked = true;
|
||||
try
|
||||
{
|
||||
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Default;
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
_startup = GeneralSettingsConfigs.Startup;
|
||||
_autoDownloadUpdates = GeneralSettingsConfigs.AutoDownloadUpdates;
|
||||
_isElevated = ShellPage.IsElevated;
|
||||
_isElevated = isElevated;
|
||||
_runElevated = GeneralSettingsConfigs.RunElevated;
|
||||
|
||||
RunningAsUserDefaultText = loader.GetString("GeneralSettings_RunningAsUserText");
|
||||
RunningAsAdminDefaultText = loader.GetString("GeneralSettings_RunningAsAdminText");
|
||||
RunningAsUserDefaultText = runAsUserText;
|
||||
RunningAsAdminDefaultText = runAsAdminText;
|
||||
|
||||
_isAdmin = ShellPage.IsUserAnAdmin;
|
||||
_isAdmin = isAdmin;
|
||||
}
|
||||
|
||||
private bool _packaged = false;
|
||||
private bool _startup = false;
|
||||
private bool _isElevated = false;
|
||||
private bool _runElevated = false;
|
||||
private bool _isAdmin = false;
|
||||
private bool _isDarkThemeRadioButtonChecked = false;
|
||||
private bool _isLightThemeRadioButtonChecked = false;
|
||||
private bool _isSystemThemeRadioButtonChecked = false;
|
||||
private bool _autoDownloadUpdates = false;
|
||||
|
||||
// Gets or sets a value indicating whether packaged.
|
||||
public bool Packaged
|
||||
{
|
||||
@@ -265,7 +259,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
_isDarkThemeRadioButtonChecked = value;
|
||||
try
|
||||
{
|
||||
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Dark;
|
||||
UpdateUIThemeCallBack(GeneralSettingsConfigs.Theme);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -291,7 +285,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
_isLightThemeRadioButtonChecked = value;
|
||||
try
|
||||
{
|
||||
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Light;
|
||||
UpdateUIThemeCallBack(GeneralSettingsConfigs.Theme);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -317,7 +311,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
_isSystemThemeRadioButtonChecked = value;
|
||||
try
|
||||
{
|
||||
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Default;
|
||||
UpdateUIThemeCallBack(GeneralSettingsConfigs.Theme);
|
||||
}
|
||||
catch
|
||||
{
|
||||
@@ -343,30 +337,30 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
|
||||
|
||||
OutGoingGeneralSettings outsettings = new OutGoingGeneralSettings(GeneralSettingsConfigs);
|
||||
|
||||
ShellPage.DefaultSndMSGCallback(outsettings.ToString());
|
||||
SendConfigMSG(outsettings.ToString());
|
||||
}
|
||||
|
||||
// callback function to launch the URL to check for updates.
|
||||
private void CheckForUpdates_Click()
|
||||
private async void CheckForUpdates_Click()
|
||||
{
|
||||
GeneralSettings settings = SettingsUtils.GetSettings<GeneralSettings>(string.Empty);
|
||||
GeneralSettings settings = SettingsUtils.GetSettings<GeneralSettings>(SettingsConfigFileFolder);
|
||||
settings.CustomActionName = "check_for_updates";
|
||||
|
||||
OutGoingGeneralSettings outsettings = new OutGoingGeneralSettings(settings);
|
||||
GeneralSettingsCustomAction customaction = new GeneralSettingsCustomAction(outsettings);
|
||||
|
||||
ShellPage.CheckForUpdatesMsgCallback?.Invoke(customaction.ToString());
|
||||
SendCheckForUpdatesConfigMSG(customaction.ToString());
|
||||
}
|
||||
|
||||
public void Restart_Elevated()
|
||||
{
|
||||
GeneralSettings settings = SettingsUtils.GetSettings<GeneralSettings>(string.Empty);
|
||||
GeneralSettings settings = SettingsUtils.GetSettings<GeneralSettings>(SettingsConfigFileFolder);
|
||||
settings.CustomActionName = "restart_elevation";
|
||||
|
||||
OutGoingGeneralSettings outsettings = new OutGoingGeneralSettings(settings);
|
||||
GeneralSettingsCustomAction customaction = new GeneralSettingsCustomAction(outsettings);
|
||||
|
||||
ShellPage.SndRestartAsAdminMsgCallback?.Invoke(customaction.ToString());
|
||||
SendRestartAsAdminConfigMSG(customaction.ToString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// 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 Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using Microsoft.PowerToys.Settings.UnitTest;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Schema;
|
||||
|
||||
namespace CommonLibTest
|
||||
{
|
||||
[TestClass]
|
||||
public class BasePTModuleSettingsTest
|
||||
{
|
||||
// Work around for System.JSON required properties:
|
||||
// https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-migrate-from-newtonsoft-how-to.
|
||||
// Test also fails when the attributes are not initialized i.e they have null values.
|
||||
[TestMethod]
|
||||
[Obsolete]
|
||||
public void ToJsonString_ShouldReturnValidJSONOfModel_WhenSuccessful()
|
||||
{
|
||||
// Arrange
|
||||
string file_name = "test\\BasePTModuleSettingsTest";
|
||||
string expectedSchemaText = @"
|
||||
{
|
||||
'$schema': 'http://json-schema.org/draft-04/schema#',
|
||||
'type': 'object',
|
||||
'properties': {
|
||||
'name': {
|
||||
'type': 'string'
|
||||
},
|
||||
'version': {
|
||||
'type': 'string'
|
||||
}
|
||||
},
|
||||
'additionalProperties': false
|
||||
}";
|
||||
|
||||
string testSettingsConfigs = new BasePTSettingsTest().ToJsonString();
|
||||
SettingsUtils.SaveSettings(testSettingsConfigs, file_name);
|
||||
JsonSchema expectedSchema = JsonSchema.Parse(expectedSchemaText);
|
||||
|
||||
// Act
|
||||
JObject actualSchema = JObject.Parse(SettingsUtils.GetSettings<BasePTSettingsTest>(file_name).ToJsonString());
|
||||
bool valid = actualSchema.IsValid(expectedSchema);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(valid);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) Microsoft Corporation
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UnitTest
|
||||
{
|
||||
public class BasePTSettingsTest : BasePTModuleSettings
|
||||
{
|
||||
public BasePTSettingsTest()
|
||||
{
|
||||
Name = string.Empty;
|
||||
Version = string.Empty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
// 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 Microsoft.PowerToys.Settings.UI.Lib.Utilities;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace CommonLibTest
|
||||
{
|
||||
[TestClass]
|
||||
public class HelperTest
|
||||
{
|
||||
public static void TestStringIsSmaller(string v1, string v2)
|
||||
{
|
||||
var res = Helper.CompareVersions(v1, v2);
|
||||
Assert.IsTrue(res < 0);
|
||||
}
|
||||
|
||||
public static void TestStringsAreEqual(string v1, string v2)
|
||||
{
|
||||
var res = Helper.CompareVersions(v1, v2);
|
||||
Assert.IsTrue(res == 0);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Helper_CompareVersions_ShouldBeEqual_WhenSuccessful()
|
||||
{
|
||||
TestStringsAreEqual("v0.0.0", "v0.0.0");
|
||||
TestStringsAreEqual("v0.1.1", "v0.1.1");
|
||||
TestStringsAreEqual("v1.1.1", "v1.1.1");
|
||||
TestStringsAreEqual("v1.999.99", "v1.999.99");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Helper_CompareVersions_ShouldBeSmaller_WhenSuccessful()
|
||||
{
|
||||
TestStringIsSmaller("v0.0.0", "v0.0.1");
|
||||
TestStringIsSmaller("v0.0.0", "v0.1.0");
|
||||
TestStringIsSmaller("v0.0.0", "v1.0.0");
|
||||
TestStringIsSmaller("v1.0.1", "v1.0.2");
|
||||
TestStringIsSmaller("v1.1.1", "v1.1.2");
|
||||
TestStringIsSmaller("v1.1.1", "v1.2.0");
|
||||
TestStringIsSmaller("v1.999.99", "v2.0.0");
|
||||
TestStringIsSmaller("v1.0.99", "v1.2.0");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(FormatException))]
|
||||
public void Helper_CompareVersions_ShouldThrowBadFormat_WhenNoVersionString()
|
||||
{
|
||||
Helper.CompareVersions("v0.0.1", string.Empty);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(FormatException))]
|
||||
public void Helper_CompareVersions_ShouldThrowBadFormat_WhenShortVersionString()
|
||||
{
|
||||
Helper.CompareVersions("v0.0.1", "v0.1");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(FormatException))]
|
||||
public void Helper_CompareVersions_ShouldThrowBadFormat_WhenLongVersionString()
|
||||
{
|
||||
Helper.CompareVersions("v0.0.1", "v0.0.0.1");
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
[ExpectedException(typeof(FormatException))]
|
||||
public void Helper_CompareVersions_ShouldThrowBadFormat_WhenItIsNotAVersionString()
|
||||
{
|
||||
Helper.CompareVersions("v0.0.1", "HelloWorld");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
// 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.IO;
|
||||
using System.Linq;
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using Microsoft.PowerToys.Settings.UnitTest;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace CommonLibTest
|
||||
{
|
||||
[TestClass]
|
||||
public class SettingsUtilsTests
|
||||
{
|
||||
public SettingsUtilsTests()
|
||||
{
|
||||
string file_name = "\\test";
|
||||
if (SettingsUtils.SettingsFolderExists(file_name))
|
||||
{
|
||||
DeleteFolder(file_name);
|
||||
}
|
||||
}
|
||||
|
||||
[TestCleanup]
|
||||
public void Cleanup()
|
||||
{
|
||||
string file_name = "\\test";
|
||||
if (SettingsUtils.SettingsFolderExists(file_name))
|
||||
{
|
||||
DeleteFolder(file_name);
|
||||
}
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SaveSettings_SaveSettingsToFile_WhenFilePathExists()
|
||||
{
|
||||
// Arrange
|
||||
string file_name = "\\test";
|
||||
string file_contents_correct_json_content = "{\"name\":\"powertoy module name\",\"version\":\"powertoy version\"}";
|
||||
|
||||
BasePTSettingsTest expected_json = JsonSerializer.Deserialize<BasePTSettingsTest>(file_contents_correct_json_content);
|
||||
|
||||
// Act
|
||||
SettingsUtils.SaveSettings(file_contents_correct_json_content, file_name);
|
||||
BasePTSettingsTest actual_json = SettingsUtils.GetSettings<BasePTSettingsTest>(file_name);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(actual_json.Equals(actual_json));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SaveSettings_ShouldCreateFile_WhenFilePathIsNotFound()
|
||||
{
|
||||
// Arrange
|
||||
string file_name = "test\\Test Folder";
|
||||
string file_contents_correct_json_content = "{\"name\":\"powertoy module name\",\"version\":\"powertoy version\"}";
|
||||
|
||||
BasePTSettingsTest expected_json = JsonSerializer.Deserialize<BasePTSettingsTest>(file_contents_correct_json_content);
|
||||
|
||||
// Act
|
||||
if (SettingsUtils.SettingsFolderExists(file_name))
|
||||
{
|
||||
DeleteFolder(file_name);
|
||||
}
|
||||
|
||||
SettingsUtils.SaveSettings(file_contents_correct_json_content, file_name);
|
||||
BasePTSettingsTest actual_json = SettingsUtils.GetSettings<BasePTSettingsTest>(file_name);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(actual_json.Equals(actual_json));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void SettingsFolderExists_ShouldReturnFalse_WhenFilePathIsNotFound()
|
||||
{
|
||||
// Arrange
|
||||
string file_name_random = "test\\" + RandomString();
|
||||
string file_name_exists = "test\\exists";
|
||||
string file_contents_correct_json_content = "{\"name\":\"powertoy module name\",\"version\":\"powertoy version\"}";
|
||||
|
||||
// Act
|
||||
bool pathNotFound = SettingsUtils.SettingsFolderExists(file_name_random);
|
||||
|
||||
SettingsUtils.SaveSettings(file_contents_correct_json_content, file_name_exists);
|
||||
bool pathFound = SettingsUtils.SettingsFolderExists(file_name_exists);
|
||||
|
||||
// Assert
|
||||
Assert.IsFalse(pathNotFound);
|
||||
Assert.IsTrue(pathFound);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void CreateSettingsFolder_ShouldCreateFolder_WhenSuccessful()
|
||||
{
|
||||
// Arrange
|
||||
string file_name = "test\\" + RandomString();
|
||||
|
||||
// Act
|
||||
SettingsUtils.CreateSettingsFolder(file_name);
|
||||
|
||||
// Assert
|
||||
Assert.IsTrue(SettingsUtils.SettingsFolderExists(file_name));
|
||||
}
|
||||
|
||||
public void DeleteFolder(string powertoy)
|
||||
{
|
||||
Directory.Delete(Path.Combine(SettingsUtils.LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"), true);
|
||||
}
|
||||
|
||||
public static string RandomString()
|
||||
{
|
||||
Random random = new Random();
|
||||
int length = 20;
|
||||
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
|
||||
|
||||
return new string(Enumerable.Repeat(chars, length)
|
||||
.Select(s => s[random.Next(s.Length)]).ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,201 @@
|
||||
// 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.IO;
|
||||
using System.Text.Json;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.ViewModels;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
|
||||
namespace ViewModelTests
|
||||
{
|
||||
[TestClass]
|
||||
public class General
|
||||
{
|
||||
public const string generalSettings_file_name = "Test\\GenealSettings";
|
||||
|
||||
[TestInitialize]
|
||||
public void Setup()
|
||||
{
|
||||
// initialize creation of test settings file.
|
||||
GeneralSettings generalSettings = new GeneralSettings();
|
||||
SettingsUtils.SaveSettings(generalSettings.ToJsonString(), generalSettings_file_name);
|
||||
}
|
||||
|
||||
[TestCleanup]
|
||||
public void CleanUp()
|
||||
{
|
||||
// delete folder created.
|
||||
if (SettingsUtils.SettingsFolderExists(generalSettings_file_name))
|
||||
{
|
||||
DeleteFolder(generalSettings_file_name);
|
||||
}
|
||||
}
|
||||
|
||||
public void DeleteFolder(string powertoy)
|
||||
{
|
||||
Directory.Delete(Path.Combine(SettingsUtils.LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"), true);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IsElevated_ShouldUpdateRunasAdminStatusAttrs_WhenSuccessful()
|
||||
{
|
||||
// Arrange
|
||||
Func<string, int> SendMockIPCConfigMSG = msg => { return 0; };
|
||||
Func<string, int> SendRestartAdminIPCMessage = msg => { return 0; };
|
||||
Func<string, int> SendCheckForUpdatesIPCMessage = msg => { return 0; };
|
||||
GeneralViewModel viewModel = new GeneralViewModel(
|
||||
"GeneralSettings_RunningAsAdminText",
|
||||
"GeneralSettings_RunningAsUserText",
|
||||
false,
|
||||
false,
|
||||
UpdateUIThemeMethod,
|
||||
SendMockIPCConfigMSG,
|
||||
SendRestartAdminIPCMessage,
|
||||
SendCheckForUpdatesIPCMessage,
|
||||
generalSettings_file_name);
|
||||
|
||||
Assert.AreEqual(viewModel.RunningAsUserDefaultText, viewModel.RunningAsText);
|
||||
Assert.IsFalse(viewModel.IsElevated);
|
||||
|
||||
// Act
|
||||
viewModel.IsElevated = true;
|
||||
|
||||
// Assert
|
||||
Assert.AreEqual(viewModel.RunningAsAdminDefaultText, viewModel.RunningAsText);
|
||||
Assert.IsTrue(viewModel.IsElevated);
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void Startup_ShouldEnableRunOnStartUp_WhenSuccessful()
|
||||
{
|
||||
// Assert
|
||||
Func<string, int> SendMockIPCConfigMSG = msg =>
|
||||
{
|
||||
OutGoingGeneralSettings snd = JsonSerializer.Deserialize<OutGoingGeneralSettings>(msg);
|
||||
Assert.IsTrue(snd.GeneralSettings.Startup);
|
||||
return 0;
|
||||
};
|
||||
|
||||
// Arrange
|
||||
Func<string, int> SendRestartAdminIPCMessage = msg => { return 0; };
|
||||
Func<string, int> SendCheckForUpdatesIPCMessage = msg => { return 0; };
|
||||
GeneralViewModel viewModel = new GeneralViewModel(
|
||||
"GeneralSettings_RunningAsAdminText",
|
||||
"GeneralSettings_RunningAsUserText",
|
||||
false,
|
||||
false,
|
||||
UpdateUIThemeMethod,
|
||||
SendMockIPCConfigMSG,
|
||||
SendRestartAdminIPCMessage,
|
||||
SendCheckForUpdatesIPCMessage,
|
||||
generalSettings_file_name);
|
||||
Assert.IsFalse(viewModel.Startup);
|
||||
|
||||
// act
|
||||
viewModel.Startup = true;
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void RunElevated_ShouldEnableAlwaysRunElevated_WhenSuccessful()
|
||||
{
|
||||
// Assert
|
||||
Func<string, int> SendMockIPCConfigMSG = msg =>
|
||||
{
|
||||
OutGoingGeneralSettings snd = JsonSerializer.Deserialize<OutGoingGeneralSettings>(msg);
|
||||
Assert.IsTrue(snd.GeneralSettings.RunElevated);
|
||||
return 0;
|
||||
};
|
||||
|
||||
Func<string, int> SendRestartAdminIPCMessage = msg => { return 0; };
|
||||
Func<string, int> SendCheckForUpdatesIPCMessage = msg => { return 0; };
|
||||
|
||||
// Arrange
|
||||
GeneralViewModel viewModel = new GeneralViewModel(
|
||||
"GeneralSettings_RunningAsAdminText",
|
||||
"GeneralSettings_RunningAsUserText",
|
||||
false,
|
||||
false,
|
||||
UpdateUIThemeMethod,
|
||||
SendMockIPCConfigMSG,
|
||||
SendRestartAdminIPCMessage,
|
||||
SendCheckForUpdatesIPCMessage,
|
||||
generalSettings_file_name);
|
||||
|
||||
Assert.IsFalse(viewModel.RunElevated);
|
||||
|
||||
// act
|
||||
viewModel.RunElevated = true;
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IsLightThemeRadioButtonChecked_ShouldThemeToLight_WhenSuccessful()
|
||||
{
|
||||
// Arrange
|
||||
GeneralViewModel viewModel = null;
|
||||
// Assert
|
||||
Func<string, int> SendMockIPCConfigMSG = msg =>
|
||||
{
|
||||
OutGoingGeneralSettings snd = JsonSerializer.Deserialize<OutGoingGeneralSettings>(msg);
|
||||
Assert.AreEqual("light", snd.GeneralSettings.Theme);
|
||||
return 0;
|
||||
};
|
||||
|
||||
Func<string, int> SendRestartAdminIPCMessage = msg => { return 0; };
|
||||
Func<string, int> SendCheckForUpdatesIPCMessage = msg => { return 0; };
|
||||
viewModel = new GeneralViewModel(
|
||||
"GeneralSettings_RunningAsAdminText",
|
||||
"GeneralSettings_RunningAsUserText",
|
||||
false,
|
||||
false,
|
||||
UpdateUIThemeMethod,
|
||||
SendMockIPCConfigMSG,
|
||||
SendRestartAdminIPCMessage,
|
||||
SendCheckForUpdatesIPCMessage,
|
||||
generalSettings_file_name);
|
||||
Assert.IsFalse(viewModel.IsLightThemeRadioButtonChecked);
|
||||
|
||||
// act
|
||||
viewModel.IsLightThemeRadioButtonChecked = true;
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public void IsDarkThemeRadioButtonChecked_ShouldThemeToDark_WhenSuccessful()
|
||||
{
|
||||
// Arrange
|
||||
// Assert
|
||||
Func<string, int> SendMockIPCConfigMSG = msg =>
|
||||
{
|
||||
OutGoingGeneralSettings snd = JsonSerializer.Deserialize<OutGoingGeneralSettings>(msg);
|
||||
Assert.AreEqual("dark", snd.GeneralSettings.Theme);
|
||||
return 0;
|
||||
};
|
||||
|
||||
Func<string, int> SendRestartAdminIPCMessage = msg => { return 0; };
|
||||
Func<string, int> SendCheckForUpdatesIPCMessage = msg => { return 0; };
|
||||
GeneralViewModel viewModel = new GeneralViewModel(
|
||||
"GeneralSettings_RunningAsAdminText",
|
||||
"GeneralSettings_RunningAsUserText",
|
||||
false,
|
||||
false,
|
||||
UpdateUIThemeMethod,
|
||||
SendMockIPCConfigMSG,
|
||||
SendRestartAdminIPCMessage,
|
||||
SendCheckForUpdatesIPCMessage,
|
||||
generalSettings_file_name);
|
||||
Assert.IsFalse(viewModel.IsDarkThemeRadioButtonChecked);
|
||||
|
||||
|
||||
|
||||
// act
|
||||
viewModel.IsDarkThemeRadioButtonChecked = true;
|
||||
}
|
||||
|
||||
public int UpdateUIThemeMethod(string themeName)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -110,7 +110,6 @@
|
||||
<Compile Include="Services\NavigationService.cs" />
|
||||
<Compile Include="ViewModels\ColorPickerViewModel.cs" />
|
||||
<Compile Include="ViewModels\Commands\ButtonClickCommand.cs" />
|
||||
<Compile Include="ViewModels\GeneralViewModel.cs" />
|
||||
<Compile Include="ViewModels\FancyZonesViewModel.cs" />
|
||||
<Compile Include="ViewModels\ImageResizerViewModel.cs" />
|
||||
<Compile Include="ViewModels\KeyboardManagerViewModel.cs" />
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Microsoft.PowerToys.Settings.UI.Views"
|
||||
xmlns:viewModel="using:Microsoft.PowerToys.Settings.UI.ViewModels"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:converters="using:Microsoft.Toolkit.Uwp.UI.Converters"
|
||||
@@ -14,7 +13,6 @@
|
||||
<Page.Resources>
|
||||
<converters:BoolToObjectConverter x:Key="BoolToVisibilityConverter" TrueValue="Collapsed" FalseValue="Visible"/>
|
||||
<converters:BoolToVisibilityConverter x:Key="VisibleIfTrueConverter"/>
|
||||
<viewModel:GeneralViewModel x:Key="eventViewModel"/>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid RowSpacing="{StaticResource DefaultRowSpacing}">
|
||||
@@ -56,25 +54,25 @@
|
||||
<TextBlock x:Uid="Admin_Mode" FontWeight="SemiBold"
|
||||
Style="{StaticResource SubtitleTextBlockStyle}"/>
|
||||
|
||||
<TextBlock Text="{Binding Mode=TwoWay, Path=RunningAsText, Source={StaticResource eventViewModel}}"
|
||||
<TextBlock Text="{x:Bind Mode=TwoWay, Path=ViewModel.RunningAsText}"
|
||||
Margin="{StaticResource SmallTopMargin}"/>
|
||||
|
||||
<Button x:Uid="GeneralPage_RestartAsAdmin_Button"
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
Style="{StaticResource AccentButtonStyle}"
|
||||
Command = "{Binding RestartElevatedButtonEventHandler, Source={StaticResource eventViewModel}}"
|
||||
IsEnabled="{Binding Mode=TwoWay, Path=IsAdminButtonEnabled, Source={StaticResource eventViewModel}}"
|
||||
Command = "{Binding RestartElevatedButtonEventHandler}"
|
||||
IsEnabled="{Binding Mode=TwoWay, Path=IsAdminButtonEnabled}"
|
||||
/>
|
||||
|
||||
<TextBlock x:Uid="General_RunAsAdminRequired"
|
||||
Foreground="{ThemeResource SystemControlErrorTextForegroundBrush}"
|
||||
Visibility="{Binding Mode=TwoWay, Path=IsElevated, Source={StaticResource eventViewModel}, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
Visibility="{Binding Mode=TwoWay, Path=IsElevated, Converter={StaticResource BoolToVisibilityConverter}}"
|
||||
Margin="0,24,0,-8" />
|
||||
|
||||
<ToggleSwitch Margin="{StaticResource SmallTopMargin}"
|
||||
x:Uid="GeneralSettings_AlwaysRunAsAdminText"
|
||||
IsEnabled="{Binding Mode=TwoWay, Path=IsElevated, Source={StaticResource eventViewModel}}"
|
||||
IsOn="{Binding Mode=TwoWay, Path=RunElevated, Source={StaticResource eventViewModel}}"/>
|
||||
IsEnabled="{Binding Mode=TwoWay, Path=IsElevated}"
|
||||
IsOn="{Binding Mode=TwoWay, Path=RunElevated}"/>
|
||||
|
||||
<HyperlinkButton NavigateUri="https://aka.ms/powertoysDetectedElevatedHelp">
|
||||
<TextBlock x:Uid="GeneralPage_ToggleSwitch_AlwaysRunElevated_Link" />
|
||||
@@ -88,20 +86,20 @@
|
||||
Margin="{StaticResource SmallTopMargin}">
|
||||
<RadioButton x:Uid="GeneralPage_Radio_Theme_Dark"
|
||||
Content="Dark"
|
||||
IsChecked="{ Binding Mode=TwoWay, Path=IsDarkThemeRadioButtonChecked, Source={StaticResource eventViewModel}}"/>
|
||||
IsChecked="{ Binding Mode=TwoWay, Path=IsDarkThemeRadioButtonChecked}"/>
|
||||
|
||||
<RadioButton x:Uid="GeneralPage_Radio_Theme_Light"
|
||||
Content="Light"
|
||||
IsChecked="{ Binding Mode=TwoWay, Path=IsLightThemeRadioButtonChecked, Source={StaticResource eventViewModel}}"/>
|
||||
IsChecked="{ Binding Mode=TwoWay, Path=IsLightThemeRadioButtonChecked}"/>
|
||||
|
||||
<RadioButton x:Uid="GeneralPage_Radio_Theme_Default"
|
||||
Content="System default"
|
||||
IsChecked="{ Binding Mode=TwoWay, Path=IsSystemThemeRadioButtonChecked, Source={StaticResource eventViewModel}}"/>
|
||||
IsChecked="{ Binding Mode=TwoWay, Path=IsSystemThemeRadioButtonChecked}"/>
|
||||
</muxc:RadioButtons>
|
||||
|
||||
<ToggleSwitch x:Uid="GeneralPage_ToggleSwitch_RunAtStartUp"
|
||||
Margin="{StaticResource SmallTopMargin}"
|
||||
IsOn="{Binding Mode=TwoWay, Path=Startup, Source={StaticResource eventViewModel}}"/>
|
||||
IsOn="{Binding Mode=TwoWay, Path=Startup}"/>
|
||||
|
||||
|
||||
|
||||
@@ -109,7 +107,7 @@
|
||||
Style="{StaticResource SettingsGroupTitleStyle}"/>
|
||||
<StackPanel Orientation="Horizontal" Margin="{StaticResource SmallTopMargin}">
|
||||
<TextBlock Text="Version: " x:Uid="General_Version" />
|
||||
<HyperlinkButton NavigateUri="https://aka.ms/installpowertoys" Margin="4,-6,0,0">
|
||||
<HyperlinkButton NavigateUri="https://github.com/microsoft/PowerToys/releases" Margin="4,-6,0,0">
|
||||
<TextBlock Text="{x:Bind ViewModel.PowerToysVersion }" />
|
||||
</HyperlinkButton>
|
||||
</StackPanel>
|
||||
@@ -118,13 +116,13 @@
|
||||
<Button x:Uid="GeneralPage_CheckForUpdates"
|
||||
Style="{StaticResource AccentButtonStyle}"
|
||||
Foreground="White"
|
||||
Command="{Binding CheckFoUpdatesEventHandler, Source={StaticResource eventViewModel}}"
|
||||
Command="{Binding CheckFoUpdatesEventHandler}"
|
||||
/>
|
||||
|
||||
<ToggleSwitch x:Uid="GeneralPage_ToggleSwitch_AutoDownloadUpdates"
|
||||
Margin="{StaticResource MediumTopMargin}"
|
||||
Visibility="{Binding Mode=TwoWay, Path=IsAdmin, Source={StaticResource eventViewModel}, Converter={StaticResource VisibleIfTrueConverter}}"
|
||||
IsOn="{Binding Mode=TwoWay, Path=AutoDownloadUpdates, Source={StaticResource eventViewModel}}"/>
|
||||
Visibility="{Binding Mode=TwoWay, Path=IsAdmin, Converter={StaticResource VisibleIfTrueConverter}}"
|
||||
IsOn="{Binding Mode=TwoWay, Path=AutoDownloadUpdates}"/>
|
||||
|
||||
</StackPanel>
|
||||
|
||||
@@ -159,15 +157,15 @@
|
||||
<TextBlock x:Uid="General_Repository"/>
|
||||
</HyperlinkButton>
|
||||
|
||||
<HyperlinkButton NavigateUri="https://aka.ms/powerToysReportBug">
|
||||
<HyperlinkButton NavigateUri="https://github.com/microsoft/PowerToys/issues">
|
||||
<TextBlock x:Uid="GeneralPage_ReportAbug"/>
|
||||
</HyperlinkButton>
|
||||
|
||||
<HyperlinkButton NavigateUri="https://aka.ms/powerToysRequestFeature">
|
||||
<HyperlinkButton NavigateUri="https://github.com/microsoft/PowerToys/issues">
|
||||
<TextBlock x:Uid="GeneralPage_RequestAFeature_URL"/>
|
||||
</HyperlinkButton>
|
||||
|
||||
<HyperlinkButton NavigateUri=" https://go.microsoft.com/fwlink/?LinkId=521839">
|
||||
<HyperlinkButton NavigateUri=" http://go.microsoft.com/fwlink/?LinkId=521839">
|
||||
<TextBlock x:Uid="GeneralPage_PrivacyStatement_URL"/>
|
||||
</HyperlinkButton>
|
||||
|
||||
|
||||
@@ -2,7 +2,9 @@
|
||||
// The Microsoft Corporation licenses this file to you under the MIT license.
|
||||
// See the LICENSE file in the project root for more information.
|
||||
|
||||
using Microsoft.PowerToys.Settings.UI.ViewModels;
|
||||
using Microsoft.PowerToys.Settings.UI.Lib.ViewModels;
|
||||
using Windows.ApplicationModel.Resources;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
|
||||
namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
@@ -23,10 +25,40 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
/// </summary>
|
||||
public GeneralPage()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.InitializeComponent();
|
||||
|
||||
ViewModel = new GeneralViewModel();
|
||||
GeneralView.DataContext = ViewModel;
|
||||
// Load string resources
|
||||
ResourceLoader loader = ResourceLoader.GetForViewIndependentUse();
|
||||
|
||||
this.ViewModel = new GeneralViewModel(
|
||||
loader.GetString("GeneralSettings_RunningAsAdminText"),
|
||||
loader.GetString("GeneralSettings_RunningAsUserText"),
|
||||
ShellPage.IsElevated,
|
||||
ShellPage.IsUserAnAdmin,
|
||||
UpdateUIThemeMethod,
|
||||
ShellPage.SendDefaultIPCMessage,
|
||||
ShellPage.SendRestartAdminIPCMessage,
|
||||
ShellPage.SendCheckForUpdatesIPCMessage);
|
||||
|
||||
DataContext = ViewModel;
|
||||
}
|
||||
|
||||
public int UpdateUIThemeMethod(string themeName)
|
||||
{
|
||||
switch (themeName)
|
||||
{
|
||||
case "light":
|
||||
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Light;
|
||||
break;
|
||||
case "dark":
|
||||
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Dark;
|
||||
break;
|
||||
case "system":
|
||||
ShellPage.ShellHandler.RequestedTheme = ElementTheme.Default;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,24 @@ namespace Microsoft.PowerToys.Settings.UI.Views
|
||||
shellFrame.Navigate(typeof(GeneralPage));
|
||||
}
|
||||
|
||||
public static int SendDefaultIPCMessage(string msg)
|
||||
{
|
||||
DefaultSndMSGCallback(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int SendCheckForUpdatesIPCMessage(string msg)
|
||||
{
|
||||
CheckForUpdatesMsgCallback(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static int SendRestartAdminIPCMessage(string msg)
|
||||
{
|
||||
SndRestartAsAdminMsgCallback(msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Set Default IPC Message callback function.
|
||||
/// </summary>
|
||||
|
||||
Reference in New Issue
Block a user