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")] [JsonPropertyName("powertoys_version")]
public string PowertoysVersion { get; set; } public string PowertoysVersion { get; set; }
[JsonPropertyName("action_name")]
public string CustomActionName { get; set; }
[JsonPropertyName("enabled")] [JsonPropertyName("enabled")]
public EnabledModules Enabled { get; set; } public EnabledModules Enabled { get; set; }
[JsonPropertyName("download_updates_automatically")]
public bool AutoDownloadUpdates { get; set; }
public GeneralSettings() public GeneralSettings()
{ {
this.Packaged = false; this.Packaged = false;
this.Startup = false; this.Startup = false;
this.IsAdmin = false; this.IsAdmin = false;
this.IsElevated = false; this.IsElevated = false;
this.AutoDownloadUpdates = false;
this.Theme = "system"; this.Theme = "system";
this.SystemTheme = "light"; this.SystemTheme = "light";
this.PowertoysVersion = "v0.15.3"; this.PowertoysVersion = "v0.15.3";
this.Enabled = new EnabledModules(); this.Enabled = new EnabledModules();
this.CustomActionName = string.Empty;
} }
// converts the current to a json string. // 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. // The Microsoft Corporation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. // 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;
using System.Text.Json.Serialization; using System.Text.Json.Serialization;
@ -12,14 +9,16 @@ namespace Microsoft.PowerToys.Settings.UI.Lib
{ {
public class PowerPreviewProperties 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() public PowerPreviewProperties()
{ {
IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL = new BoolProperty(); EnableSvg = new BoolProperty();
PREVPANE_MD_BOOL_TOGGLE_CONTROLL_ID = new BoolProperty(); EnableMd = new BoolProperty();
} }
public override string ToString() public override string ToString()

View File

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

View File

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

View File

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

View File

@ -524,4 +524,16 @@
<data name="On.Content" xml:space="preserve"> <data name="On.Content" xml:space="preserve">
<value>On</value> <value>On</value>
</data> </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> </root>

View File

@ -56,6 +56,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
} }
_startup = GeneralSettingsConfigs.Startup; _startup = GeneralSettingsConfigs.Startup;
_autoDownloadUpdates = GeneralSettingsConfigs.AutoDownloadUpdates;
} }
private bool _packaged = false; private bool _packaged = false;
@ -65,6 +66,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
private bool _isDarkThemeRadioButtonChecked = false; private bool _isDarkThemeRadioButtonChecked = false;
private bool _isLightThemeRadioButtonChecked = false; private bool _isLightThemeRadioButtonChecked = false;
private bool _isSystemThemeRadioButtonChecked = false; private bool _isSystemThemeRadioButtonChecked = false;
private bool _autoDownloadUpdates = false;
// Gets or sets a value indicating whether packaged. // Gets or sets a value indicating whether packaged.
public bool Packaged public bool Packaged
@ -97,6 +99,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
if (_startup != value) if (_startup != value)
{ {
_startup = value; _startup = value;
GeneralSettingsConfigs.Startup = value;
RaisePropertyChanged(); 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 public bool IsDarkThemeRadioButtonChecked
{ {
get get
@ -211,15 +232,17 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
await Launcher.LaunchUriAsync(new Uri("https://github.com/microsoft/PowerToys/releases")); 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); GeneralSettings settings = SettingsUtils.GetSettings<GeneralSettings>(string.Empty);
settings.RunElevated = true; settings.CustomActionName = "restart_elevation";
OutGoingGeneralSettings outsettings = new OutGoingGeneralSettings(settings); OutGoingGeneralSettings outsettings = new OutGoingGeneralSettings(settings);
GeneralSettingsCustomAction customaction = new GeneralSettingsCustomAction(outsettings);
if (ShellPage.DefaultSndMSGCallback != null) 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); SettingsUtils.SaveSettings(Settings.ToJsonString(), ModuleName);
} }
this._svgRenderIsEnabled = Settings.properties.IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL.Value; this._svgRenderIsEnabled = Settings.properties.EnableSvg.Value;
this._mdRenderIsEnabled = Settings.properties.PREVPANE_MD_BOOL_TOGGLE_CONTROLL_ID.Value; this._mdRenderIsEnabled = Settings.properties.EnableMd.Value;
} }
private bool _svgRenderIsEnabled = false; private bool _svgRenderIsEnabled = false;
private bool _mdRenderIsEnabled = false; private bool _mdRenderIsEnabled = false;
public bool SVGRenderIsEnebled public bool SVGRenderIsEnabled
{ {
get get
{ {
@ -46,13 +46,13 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
if (value != _svgRenderIsEnabled) if (value != _svgRenderIsEnabled)
{ {
_svgRenderIsEnabled = value; _svgRenderIsEnabled = value;
Settings.properties.IDS_PREVPANE_SVG_BOOL_TOGGLE_CONTROLL.Value = value; Settings.properties.EnableSvg.Value = value;
RaisePropertyChanged(); RaisePropertyChanged();
} }
} }
} }
public bool MDRenderIsEnebled public bool MDRenderIsEnabled
{ {
get get
{ {
@ -64,7 +64,7 @@ namespace Microsoft.PowerToys.Settings.UI.ViewModels
if (value != _mdRenderIsEnabled) if (value != _mdRenderIsEnabled)
{ {
_mdRenderIsEnabled = value; _mdRenderIsEnabled = value;
Settings.properties.PREVPANE_MD_BOOL_TOGGLE_CONTROLL_ID.Value = value; Settings.properties.EnableMd.Value = value;
RaisePropertyChanged(); RaisePropertyChanged();
} }
} }

View File

@ -52,20 +52,24 @@
<ToggleSwitch x:Uid="GeneralPage_ToggleSwitch_RunAtStartUp" <ToggleSwitch x:Uid="GeneralPage_ToggleSwitch_RunAtStartUp"
Margin="{StaticResource SmallTopMargin}" 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}"> <muxc:RadioButtons x:Uid="RadioButtons_Name_Theme" Margin="{StaticResource SmallTopMargin}">
<RadioButton x:Uid="GeneralPage_Radio_Theme_Dark" <RadioButton x:Uid="GeneralPage_Radio_Theme_Dark"
Content="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" <RadioButton x:Uid="GeneralPage_Radio_Theme_Light"
Content="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" <RadioButton x:Uid="GeneralPage_Radio_Theme_Default"
Content="System default" Content="System default"
IsChecked="{ Binding Mode=TwoWay, Path=IsSystemThemeRadioButtonChecked}"/> IsChecked="{ Binding Mode=TwoWay, Path=IsSystemThemeRadioButtonChecked, Source={StaticResource eventViewModel}}"/>
</muxc:RadioButtons> </muxc:RadioButtons>
<Button x:Uid="GeneralPage_RestartAsAdmin_Button" <Button x:Uid="GeneralPage_RestartAsAdmin_Button"
@ -73,7 +77,6 @@
Style="{StaticResource AccentButtonStyle}" Style="{StaticResource AccentButtonStyle}"
Command = "{Binding RestartElevatedButtonEventHandler, Source={StaticResource eventViewModel}}" Command = "{Binding RestartElevatedButtonEventHandler, Source={StaticResource eventViewModel}}"
/> />
</StackPanel> </StackPanel>
<StackPanel x:Name="SidePanel" <StackPanel x:Name="SidePanel"
@ -108,8 +111,10 @@
NavigateUri=" http://go.microsoft.com/fwlink/?LinkId=521839" /> NavigateUri=" http://go.microsoft.com/fwlink/?LinkId=521839" />
<HyperlinkButton x:Uid="OpenSource_Notice" <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> </StackPanel>
</Grid> </Grid>
</Page> </Page>

View File

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

View File

@ -127,6 +127,7 @@
<Compile Include="UnitTestApp.xaml.cs"> <Compile Include="UnitTestApp.xaml.cs">
<DependentUpon>UnitTestApp.xaml</DependentUpon> <DependentUpon>UnitTestApp.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="ViewModelTests\PowerPreview.cs" />
<Compile Include="ViewModelTests\ShortcutGuide.cs" /> <Compile Include="ViewModelTests\ShortcutGuide.cs" />
<Compile Include="ViewModelTests\PowerLauncherViewModelTest.cs" /> <Compile Include="ViewModelTests\PowerLauncherViewModelTest.cs" />
</ItemGroup> </ItemGroup>
@ -183,4 +184,4 @@
<Target Name="AfterBuild"> <Target Name="AfterBuild">
</Target> </Target>
--> -->
</Project> </Project>

View File

@ -38,6 +38,11 @@ namespace ViewModelTests
{ {
DeleteFolder(generalSettings_file_name); DeleteFolder(generalSettings_file_name);
} }
if (SettingsUtils.SettingsFolderExists(Module))
{
DeleteFolder(Module);
}
} }
public void DeleteFolder(string powertoy) 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] [TestClass]
public class ShortcutGuide public class ShortcutGuide
{ {
private const string ModuleName = "Shortcut Guide";
[TestInitialize] [TestInitialize]
public void Setup() public void Setup()
{ {
@ -32,10 +34,15 @@ namespace ViewModelTests
public void CleanUp() public void CleanUp()
{ {
// delete folder created. // delete folder created.
string file_name = "\\test"; string generalSettings_file_name = string.Empty;
if (SettingsUtils.SettingsFolderExists(file_name)) 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,
nullptr, nullptr,
FALSE, FALSE,
EXTENDED_STARTUPINFO_PRESENT, 0,
nullptr, nullptr,
nullptr, nullptr,
&siex.StartupInfo, &siex.StartupInfo,
@ -262,7 +262,6 @@ void run_settings_window()
executable_args.append(settings_theme); executable_args.append(settings_theme);
BOOL process_created = false; BOOL process_created = false;
if (is_process_elevated()) if (is_process_elevated())
{ {
process_created = run_settings_non_elevated(executable_path.c_str(), executable_args.data(), &process_info); 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) if (g_message_pipe != nullptr)
{ {
MessageBox(g_main_wnd, msg.c_str(), L"From Webview", MB_OK);
g_message_pipe->send(msg); g_message_pipe->send(msg);
} }
else else