fix: Start as Admin Error: Unable to open app when running elevated (#2411)

* fixed run-elevated error and powerpreview settings not working

* removed EXTENDED_STARTUPINFO_PRESENT flag

* removed test string

* Update Microsoft.PowerToys.Settings.UnitTest.csproj

* Rename PowerLauncher.cs to PowerLauncherViewModelTest.cs
This commit is contained in:
Lavius Motileng 2020-05-03 03:17:06 -07:00 committed by GitHub
parent 8e18104f38
commit b428fc97e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 208 additions and 37 deletions

View File

@ -41,19 +41,27 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
[JsonPropertyName("powertoys_version")]
public string PowertoysVersion { get; set; }
[JsonPropertyName("action_name")]
public string CustomActionName { get; set; }
[JsonPropertyName("enabled")]
public EnabledModules Enabled { get; set; }
[JsonPropertyName("download_updates_automatically")]
public bool AutoDownloadUpdates { get; set; }
public GeneralSettings()
{
this.Packaged = false;
this.Startup = false;
this.IsAdmin = false;
this.IsElevated = false;
this.AutoDownloadUpdates = false;
this.Theme = "system";
this.SystemTheme = "light";
this.PowertoysVersion = "v0.15.3";
this.Enabled = new EnabledModules();
this.CustomActionName = string.Empty;
}
// converts the current to a json string.

View File

@ -0,0 +1,25 @@
using System.Text.Json;
using System.Text.Json.Serialization;
namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class GeneralSettingsCustomAction
{
[JsonPropertyName("action")]
public OutGoingGeneralSettings GeneralSettingsAction { get; set; }
public GeneralSettingsCustomAction()
{
}
public GeneralSettingsCustomAction(OutGoingGeneralSettings action)
{
GeneralSettingsAction = action;
}
public override string ToString()
{
return JsonSerializer.Serialize(this);
}
}
}

View File

@ -2,9 +2,6 @@
// 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.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
@ -12,14 +9,16 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class PowerPreviewProperties
{
public BoolProperty IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL { get; set; }
[JsonPropertyName("svg-previewer-toggle-setting")]
public BoolProperty EnableSvg { get; set; }
public BoolProperty PREVPANE_MD_BOOL_TOGGLE_CONTROLL_ID { get; set; }
[JsonPropertyName("md-previewer-toggle-setting")]
public BoolProperty EnableMd { get; set; }
public PowerPreviewProperties()
{
IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL = new BoolProperty();
PREVPANE_MD_BOOL_TOGGLE_CONTROLL_ID = new BoolProperty();
EnableSvg = new BoolProperty();
EnableMd = new BoolProperty();
}
public override string ToString()

View File

@ -15,7 +15,6 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
public SndModuleSettings()
{
}
public SndModuleSettings(T settings)

View File

@ -12,12 +12,16 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{
public class SndPowerPreviewSettings
{
[JsonPropertyName("File Explorer Preview")]
public PowerPreviewSettings File_Explorer_Preview { get; set; }
[JsonPropertyName("File Explorer")]
public PowerPreviewSettings FileExplorerPreviewSettings { get; set; }
public SndPowerPreviewSettings()
{
}
public SndPowerPreviewSettings(PowerPreviewSettings settings)
{
File_Explorer_Preview = settings;
FileExplorerPreviewSettings = settings;
}
public string ToJsonString()

View File

@ -57,7 +57,6 @@
<ItemGroup>
<PackageReference Include="Microsoft.Toolkit.UI.XamlHost" Version="6.0.1" />
<PackageReference Include="Microsoft.Toolkit.Uwp.UI" Version="6.0.0" />
<PackageReference Include="Microsoft.Toolkit.Wpf.UI.Controls" Version="6.0.1" />
<PackageReference Include="Microsoft.Toolkit.Wpf.UI.XamlHost" Version="6.0.1" />
<PackageReference Include="StyleCop.Analyzers" Version="1.1.118">

View File

@ -524,4 +524,16 @@
<data name="On.Content" xml:space="preserve">
<value>On</value>
</data>
<data name="GeneralPage_ToggleSwitch_AlwaysRunElevated.Header" xml:space="preserve">
<value>Always Run as Admin</value>
</data>
<data name="GeneralPage_ToggleSwitch_AlwaysRunElevated_Link.Content" xml:space="preserve">
<value>Learn about Admin mode</value>
</data>
<data name="GeneralPage_ToggleSwitch_AutoDownloadUpdates.Header" xml:space="preserve">
<value>Download updates automatically</value>
</data>
<data name="GeneralPage_ToggleSwitch_RunningAsAdminNote.Text" xml:space="preserve">
<value>Currently running as administrator</value>
</data>
</root>

View File

@ -56,6 +56,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
}
_startup = GeneralSettingsConfigs.Startup;
_autoDownloadUpdates = GeneralSettingsConfigs.AutoDownloadUpdates;
}
private bool _packaged = false;
@ -65,6 +66,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
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
@ -97,6 +99,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
if (_startup != value)
{
_startup = value;
GeneralSettingsConfigs.Startup = value;
RaisePropertyChanged();
}
}
@ -138,6 +141,24 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
}
}
public bool AutoDownloadUpdates
{
get
{
return _autoDownloadUpdates;
}
set
{
if (_autoDownloadUpdates != value)
{
_autoDownloadUpdates = value;
GeneralSettingsConfigs.AutoDownloadUpdates = value;
RaisePropertyChanged();
}
}
}
public bool IsDarkThemeRadioButtonChecked
{
get
@ -211,15 +232,17 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
await Launcher.LaunchUriAsync(new Uri("https://github.com/microsoft/PowerToys/releases"));
}
private void Restart_Elevated()
public void Restart_Elevated()
{
GeneralSettings settings = SettingsUtils.GetSettings<GeneralSettings>(string.Empty);
settings.RunElevated = true;
settings.CustomActionName = "restart_elevation";
OutGoingGeneralSettings outsettings = new OutGoingGeneralSettings(settings);
GeneralSettingsCustomAction customaction = new GeneralSettingsCustomAction(outsettings);
if (ShellPage.DefaultSndMSGCallback != null)
{
ShellPage.DefaultSndMSGCallback(outsettings.ToString());
ShellPage.DefaultSndMSGCallback(customaction.ToString());
}
}
}

View File

@ -27,14 +27,14 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
SettingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
}
this._svgRenderIsEnabled = Settings.properties.IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL.Value;
this._mdRenderIsEnabled = Settings.properties.PREVPANE_MD_BOOL_TOGGLE_CONTROLL_ID.Value;
this._svgRenderIsEnabled = Settings.properties.EnableSvg.Value;
this._mdRenderIsEnabled = Settings.properties.EnableMd.Value;
}
private bool _svgRenderIsEnabled = false;
private bool _mdRenderIsEnabled = false;
public bool SVGRenderIsEnebled
public bool SVGRenderIsEnabled
{
get
{
@ -46,13 +46,13 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
if (value != _svgRenderIsEnabled)
{
_svgRenderIsEnabled = value;
Settings.properties.IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL.Value = value;
Settings.properties.EnableSvg.Value = value;
RaisePropertyChanged();
}
}
}
public bool MDRenderIsEnebled
public bool MDRenderIsEnabled
{
get
{
@ -64,7 +64,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
if (value != _mdRenderIsEnabled)
{
_mdRenderIsEnabled = value;
Settings.properties.PREVPANE_MD_BOOL_TOGGLE_CONTROLL_ID.Value = value;
Settings.properties.EnableMd.Value = value;
RaisePropertyChanged();
}
}

View File

@ -52,20 +52,24 @@
<ToggleSwitch x:Uid="GeneralPage_ToggleSwitch_RunAtStartUp"
Margin="{StaticResource SmallTopMargin}"
IsOn="{Binding Mode=TwoWay, Path=Startup}"/>
IsOn="{Binding Mode=TwoWay, Path=Startup, Source={StaticResource eventViewModel}}"/>
<ToggleSwitch x:Uid="GeneralPage_ToggleSwitch_AutoDownloadUpdates"
Margin="{StaticResource SmallTopMargin}"
IsOn="{Binding Mode=TwoWay, Path=AutoDownloadUpdates, Source={StaticResource eventViewModel}}"/>
<muxc:RadioButtons x:Uid="RadioButtons_Name_Theme" Margin="{StaticResource SmallTopMargin}">
<RadioButton x:Uid="GeneralPage_Radio_Theme_Dark"
Content="Dark"
IsChecked="{ Binding Mode=TwoWay, Path=IsDarkThemeRadioButtonChecked}"/>
IsChecked="{ Binding Mode=TwoWay, Path=IsDarkThemeRadioButtonChecked, Source={StaticResource eventViewModel}}"/>
<RadioButton x:Uid="GeneralPage_Radio_Theme_Light"
Content="Light"
IsChecked="{ Binding Mode=TwoWay, Path=IsLightThemeRadioButtonChecked}"/>
IsChecked="{ Binding Mode=TwoWay, Path=IsLightThemeRadioButtonChecked, Source={StaticResource eventViewModel}}"/>
<RadioButton x:Uid="GeneralPage_Radio_Theme_Default"
Content="System default"
IsChecked="{ Binding Mode=TwoWay, Path=IsSystemThemeRadioButtonChecked}"/>
IsChecked="{ Binding Mode=TwoWay, Path=IsSystemThemeRadioButtonChecked, Source={StaticResource eventViewModel}}"/>
</muxc:RadioButtons>
<Button x:Uid="GeneralPage_RestartAsAdmin_Button"
@ -73,7 +77,6 @@
Style="{StaticResource AccentButtonStyle}"
Command = "{Binding RestartElevatedButtonEventHandler, Source={StaticResource eventViewModel}}"
/>
</StackPanel>
<StackPanel x:Name="SidePanel"
@ -108,8 +111,10 @@
NavigateUri=" http://go.microsoft.com/fwlink/?LinkId=521839" />
<HyperlinkButton x:Uid="OpenSource_Notice"
NavigateUri="https://github.com/microsoft/PowerToys/blob/master/NOTICE.md"
/>
NavigateUri="https://github.com/microsoft/PowerToys/blob/master/NOTICE.md"/>
<HyperlinkButton x:Uid="GeneralPage_ToggleSwitch_AlwaysRunElevated_Link"
NavigateUri="https://github.com/microsoft/PowerToys/blob/master/doc/devdocs/run-as-admin-detection.md"/>
</StackPanel>
</Grid>
</Page>

View File

@ -46,11 +46,11 @@
<ToggleSwitch x:Uid="FileEplorerPreview_ToggleSwitch_Preview_SVG"
Margin="{StaticResource SmallTopMargin}"
IsOn="{Binding Mode=TwoWay, Path=SVGRenderIsEnebled}" />
IsOn="{Binding Mode=TwoWay, Path=SVGRenderIsEnabled}" />
<ToggleSwitch x:Uid="FileEplorerPreview_ToggleSwitch_Preview_MD"
Margin="{StaticResource SmallTopMargin}"
IsOn="{Binding Mode=TwoWay, Path=MDRenderIsEnebled}" />
IsOn="{Binding Mode=TwoWay, Path=MDRenderIsEnabled}" />
</StackPanel>
<StackPanel x:Name="SidePanel"

View File

@ -127,6 +127,7 @@
<Compile Include="UnitTestApp.xaml.cs">
<DependentUpon>UnitTestApp.xaml</DependentUpon>
</Compile>
<Compile Include="ViewModelTests\PowerPreview.cs" />
<Compile Include="ViewModelTests\ShortcutGuide.cs" />
<Compile Include="ViewModelTests\PowerLauncherViewModelTest.cs" />
</ItemGroup>

View File

@ -38,6 +38,11 @@ namespace ViewModelTests
{
DeleteFolder(generalSettings_file_name);
}
if (SettingsUtils.SettingsFolderExists(Module))
{
DeleteFolder(Module);
}
}
public void DeleteFolder(string powertoy)

View File

@ -0,0 +1,86 @@
using Microsoft.PowerToys.Settings.UI.Lib;
using Microsoft.PowerToys.Settings.UI.ViewModels;
using Microsoft.PowerToys.Settings.UI.Views;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace ViewModelTests
{
[TestClass]
public class PowerPreview
{
public const string Module = "File Explorer";
[TestInitialize]
public void Setup()
{
// initialize creation of test settings file.
GeneralSettings generalSettings = new GeneralSettings();
PowerPreviewSettings powerpreview = new PowerPreviewSettings();
SettingsUtils.SaveSettings(generalSettings.ToJsonString());
SettingsUtils.SaveSettings(powerpreview.ToJsonString(), powerpreview.name);
}
[TestCleanup]
public void CleanUp()
{
// delete folder created.
string generalSettings_file_name = string.Empty;
if (SettingsUtils.SettingsFolderExists(generalSettings_file_name))
{
DeleteFolder(generalSettings_file_name);
}
if (SettingsUtils.SettingsFolderExists(Module))
{
DeleteFolder(Module);
}
}
public void DeleteFolder(string powertoy)
{
Directory.Delete(Path.Combine(SettingsUtils.LocalApplicationDataFolder(), $"Microsoft\\PowerToys\\{powertoy}"), true);
}
[TestMethod]
public void SVGRenderIsEnabled_ShouldPrevHandler_WhenSuccessful()
{
// arrange
PowerPreviewViewModel viewModel = new PowerPreviewViewModel();
// Assert
ShellPage.DefaultSndMSGCallback = msg =>
{
SndModuleSettings<SndPowerPreviewSettings> snd = JsonSerializer.Deserialize<SndModuleSettings<SndPowerPreviewSettings>>(msg);
Assert.IsTrue(snd.powertoys.FileExplorerPreviewSettings.properties.EnableSvg.Value);
};
// act
viewModel.SVGRenderIsEnabled = true;
}
[TestMethod]
public void MDRenderIsEnabled_ShouldPrevHandler_WhenSuccessful()
{
// arrange
PowerPreviewViewModel viewModel = new PowerPreviewViewModel();
// Assert
ShellPage.DefaultSndMSGCallback = msg =>
{
SndModuleSettings<SndPowerPreviewSettings> snd = JsonSerializer.Deserialize<SndModuleSettings<SndPowerPreviewSettings>>(msg);
Assert.IsTrue(snd.powertoys.FileExplorerPreviewSettings.properties.EnableMd.Value);
};
// act
viewModel.MDRenderIsEnabled = true;
}
}
}

View File

@ -15,6 +15,8 @@ namespace ViewModelTests
[TestClass]
public class ShortcutGuide
{
private const string ModuleName = "Shortcut Guide";
[TestInitialize]
public void Setup()
{
@ -32,10 +34,15 @@ namespace ViewModelTests
public void CleanUp()
{
// delete folder created.
string file_name = "\\test";
if (SettingsUtils.SettingsFolderExists(file_name))
string generalSettings_file_name = string.Empty;
if (SettingsUtils.SettingsFolderExists(generalSettings_file_name))
{
DeleteFolder(file_name);
DeleteFolder(generalSettings_file_name);
}
if (SettingsUtils.SettingsFolderExists(ModuleName))
{
DeleteFolder(ModuleName);
}
}

View File

@ -197,7 +197,7 @@ BOOL run_settings_non_elevated(LPCWSTR executable_path, LPWSTR executable_args,
nullptr,
nullptr,
FALSE,
EXTENDED_STARTUPINFO_PRESENT,
0,
nullptr,
nullptr,
&siex.StartupInfo,
@ -262,7 +262,6 @@ void run_settings_window()
executable_args.append(settings_theme);
BOOL process_created = false;
if (is_process_elevated())
{
process_created = run_settings_non_elevated(executable_path.c_str(), executable_args.data(), &process_info);

View File

@ -129,7 +129,6 @@ void send_message_to_powertoys_runner(const std::wstring& msg)
{
if (g_message_pipe != nullptr)
{
MessageBox(g_main_wnd, msg.c_str(), L"From Webview", MB_OK);
g_message_pipe->send(msg);
}
else