Compare commits

...
5 Commits
Author SHA1 Message Date
Alexandru Macocian 6c2d4a1e70 No longer require administrator rights for normal usage.
Request elevation only in necesarry parts of the code.
Request elevation on update.
After update, launch application without elevation.
2021-04-24 01:20:36 +02:00
Alexandru Macocian be03f1a32d Run updates as admin 2021-04-23 23:37:01 +02:00
Alexandru Macocian 3ed1cc453a Implemented functionality to launch guildwars with lower privilege. 2021-04-23 20:24:28 +02:00
Alexandru Macocian 16030063ed Fix skill icon not unloading.
Moved all help icons on same side.
2021-04-23 19:52:09 +02:00
Alexandru Macocian 458696ad8f Fixed a bug where skill templates would try to load the image for No Skill.
Fixed a bug where build template manager would delete saved template.
2021-04-23 17:28:12 +02:00
20 changed files with 301 additions and 57 deletions
@@ -10,5 +10,7 @@ namespace Daybreak.Configuration
public int ToolboxAutoLaunchDelay { get; set; } = 5000;
[JsonProperty("DynamicBuildLoading")]
public bool DynamicBuildLoading { get; set; } = true;
[JsonProperty("LaunchGuildwarsAsCurrentUser")]
public bool LaunchGuildwarsAsCurrentUser { get; set; } = true;
}
}
@@ -7,6 +7,7 @@ using Daybreak.Services.Credentials;
using Daybreak.Services.IconRetrieve;
using Daybreak.Services.Logging;
using Daybreak.Services.Mutex;
using Daybreak.Services.Privilege;
using Daybreak.Services.Runtime;
using Daybreak.Services.Screenshots;
using Daybreak.Services.Updater;
@@ -37,6 +38,7 @@ namespace Daybreak.Configuration
serviceProducer.RegisterSingleton<IRuntimeStore, RuntimeStore>();
serviceProducer.RegisterSingleton<IBuildTemplateManager, BuildTemplateManager>();
serviceProducer.RegisterSingleton<IIconRetriever, IconRetriever>();
serviceProducer.RegisterSingleton<IPrivilegeManager, PrivilegeManager>();
}
public static void RegisterLifetimeServices(IApplicationLifetimeProducer applicationLifetimeProducer)
{
@@ -60,6 +62,7 @@ namespace Daybreak.Configuration
viewProducer.RegisterView<ExecutablesView>();
viewProducer.RegisterView<BuildTemplateView>();
viewProducer.RegisterView<BuildsListView>();
viewProducer.RegisterView<RequestElevationView>();
}
}
}
@@ -25,11 +25,11 @@
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="Primary Profession: " FontSize="16" Foreground="White"></TextBlock>
<ListView FontSize="16" Foreground="White" Grid.Column="1" BorderThickness="0"
<TextBlock Text="Primary Profession: " FontSize="16" Foreground="White" Grid.Column="1"></TextBlock>
<ListView FontSize="16" Foreground="White" Grid.Column="2" BorderThickness="0"
Background="Transparent" ItemsSource="{Binding ElementName=_this, Path=Professions, Mode=OneWay}"
SelectedItem="{Binding ElementName=_this, Path=PrimaryProfession, Mode=TwoWay}" Height="30"
SelectionMode="Single" ScrollViewer.VerticalScrollBarVisibility="Disabled"
@@ -43,17 +43,17 @@
<behaviors:ScrollIntoView></behaviors:ScrollIntoView>
</interactivity:Interaction.Behaviors>
</ListView>
<local:HelpButton Grid.Column="2" Foreground="White" Width="20" Height="20" Margin="3"
<local:HelpButton Grid.Column="0" Foreground="White" Width="20" Height="20" Margin="3"
Clicked="HelpButtonPrimary_Clicked" Cursor="Hand"></local:HelpButton>
</Grid>
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="Secondary Profession: " FontSize="16" Foreground="White"></TextBlock>
<ListView FontSize="16" Foreground="White" Grid.Column="1" BorderThickness="0"
<TextBlock Text="Secondary Profession: " FontSize="16" Foreground="White" Grid.Column="1"></TextBlock>
<ListView FontSize="16" Foreground="White" Grid.Column="2" BorderThickness="0"
Background="Transparent" ItemsSource="{Binding ElementName=_this, Path=Professions, Mode=OneWay}"
SelectedItem="{Binding ElementName=_this, Path=SecondaryProfession, Mode=TwoWay}" Height="30"
SelectionMode="Single" ScrollViewer.VerticalScrollBarVisibility="Disabled"
@@ -67,7 +67,7 @@
<behaviors:ScrollIntoView></behaviors:ScrollIntoView>
</interactivity:Interaction.Behaviors>
</ListView>
<local:HelpButton Grid.Column="2" Foreground="White" Width="20" Height="20" Margin="3"
<local:HelpButton Grid.Column="0" Foreground="White" Width="20" Height="20" Margin="3"
Clicked="HelpButtonSecondary_Clicked" Cursor="Hand"></local:HelpButton>
</Grid>
<Grid Grid.Row="3">
@@ -48,15 +48,22 @@ namespace Daybreak.Controls
private void SkillTemplate_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is Skill)
if (e.NewValue is Skill skill)
{
Task.Run(() => GetImageStream(e.NewValue.As<Skill>())).ContinueWith((previousTask) =>
if (skill != Skill.NoSkill)
{
this.Dispatcher.Invoke(() =>
Task.Run(() => GetImageStream(skill)).ContinueWith((previousTask) =>
{
this.ImageSource = GetImageSource(previousTask.Result);
this.Dispatcher.Invoke(() =>
{
this.ImageSource = GetImageSource(previousTask.Result);
});
});
});
}
else if (this.ImageSource is not null)
{
this.ImageSource = null;
}
}
}
+2 -2
View File
@@ -9,8 +9,7 @@
<CopyLocalLockFileAssemblies>false</CopyLocalLockFileAssemblies>
<LangVersion>preview</LangVersion>
<ApplicationIcon>Daybreak.ico</ApplicationIcon>
<Version>0.7.5</Version>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Version>0.8.0</Version>
</PropertyGroup>
<ItemGroup>
@@ -22,6 +21,7 @@
<PackageReference Include="SystemExtensions.NetStandard" Version="1.1.4" />
<PackageReference Include="WCL" Version="1.0.2" />
<PackageReference Include="WpfExtended" Version="0.2.0" />
<PackageReference Include="WpfScreenHelper" Version="1.0.0" />
</ItemGroup>
<ItemGroup>
+11
View File
@@ -0,0 +1,11 @@
using System;
namespace Daybreak.Models
{
public sealed class ElevationRequest
{
public object DataContext { get; set; }
public Type View { get; set; }
public string MessageToUser { get; set; }
}
}
@@ -3,7 +3,9 @@ using Daybreak.Services.Configuration;
using Daybreak.Services.Credentials;
using Daybreak.Services.Logging;
using Daybreak.Services.Mutex;
using Daybreak.Services.Privilege;
using Daybreak.Utils;
using Daybreak.Views;
using Microsoft.Win32;
using Pepa.Wpf.Utilities;
using System;
@@ -15,6 +17,7 @@ using System.Linq;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
namespace Daybreak.Services.ApplicationLauncher
{
@@ -30,6 +33,7 @@ namespace Daybreak.Services.ApplicationLauncher
private readonly ICredentialManager credentialManager;
private readonly IMutexHandler mutexHandler;
private readonly ILogger logger;
private readonly IPrivilegeManager privilegeManager;
public bool IsTexmodRunning => TexModProcessDetected();
public bool IsGuildwarsRunning => this.GuildwarsProcessDetected();
@@ -39,12 +43,14 @@ namespace Daybreak.Services.ApplicationLauncher
IConfigurationManager configurationManager,
ICredentialManager credentialManager,
IMutexHandler mutexHandler,
ILogger logger)
ILogger logger,
IPrivilegeManager privilegeManager)
{
this.logger = logger.ThrowIfNull(nameof(logger));
this.mutexHandler = mutexHandler.ThrowIfNull(nameof(mutexHandler));
this.credentialManager = credentialManager.ThrowIfNull(nameof(credentialManager));
this.configurationManager = configurationManager.ThrowIfNull(nameof(configurationManager));
this.privilegeManager = privilegeManager.ThrowIfNull(nameof(privilegeManager));
}
public async Task LaunchGuildwars()
@@ -56,6 +62,12 @@ namespace Daybreak.Services.ApplicationLauncher
{
if (configuration.ExperimentalFeatures.MultiLaunchSupport is true)
{
if (this.privilegeManager.AdminPrivileges is false)
{
this.privilegeManager.RequestAdminPrivileges<MainView>("You need administrator rights in order to start using multi-launch");
return;
}
ClearGwLocks();
}
@@ -103,6 +115,33 @@ namespace Daybreak.Services.ApplicationLauncher
});
}
public void RestartDaybreakAsAdmin()
{
this.logger.LogInformation("Restarting daybreak with admin rights");
var processName = Process.GetCurrentProcess()?.MainModule?.FileName;
if (processName.IsNullOrWhiteSpace() || File.Exists(processName) is false)
{
throw new InvalidOperationException("Unable to find executable. Aborting restart");
}
var process = new Process()
{
StartInfo = new()
{
Verb = "runas",
WorkingDirectory = Environment.CurrentDirectory,
UseShellExecute = true,
FileName = processName
}
};
if (process.Start() is false)
{
throw new InvalidOperationException($"Unable to start {processName} as admin");
}
Application.Current.Shutdown();
}
private void LaunchGuildwarsProcess(string email, Models.SecureString password, string character)
{
var executable = this.configurationManager.GetConfiguration().GuildwarsPaths.Where(path => path.Default).FirstOrDefault();
@@ -129,6 +168,18 @@ namespace Daybreak.Services.ApplicationLauncher
args.Add(character);
}
var identity = this.configurationManager.GetConfiguration().ExperimentalFeatures.LaunchGuildwarsAsCurrentUser ?
System.Security.Principal.WindowsIdentity.GetCurrent().Name :
System.Security.Principal.WindowsIdentity.GetAnonymous().Name;
this.logger.LogInformation($"Launching guildwars as [{identity}] identity");
var process = new Process()
{
StartInfo = new ProcessStartInfo
{
Arguments = string.Join(" ", args),
UserName = identity
}
};
if (Process.Start(executable.Path, args) is null)
{
throw new InvalidOperationException($"Unable to launch {executable}");
@@ -10,5 +10,6 @@ namespace Daybreak.Services.ApplicationLauncher
Task LaunchGuildwars();
Task LaunchGuildwarsToolbox();
Task LaunchTexmod();
void RestartDaybreakAsAdmin();
}
}
@@ -68,13 +68,12 @@ namespace Daybreak.Services.BuildTemplates
public void SaveBuild(BuildEntry buildEntry)
{
var encodedBuild = this.EncodeTemplate(buildEntry.Build);
File.WriteAllText($"{BuildsPath}\\{buildEntry.Name}.txt", encodedBuild);
if (string.IsNullOrWhiteSpace(buildEntry.PreviousName))
{
return;
File.Delete($"{BuildsPath}\\{buildEntry.PreviousName}.txt");
}
File.Delete($"{BuildsPath}\\{buildEntry.PreviousName}.txt");
File.WriteAllText($"{BuildsPath}\\{buildEntry.Name}.txt", encodedBuild);
}
public void RemoveBuild(BuildEntry buildEntry)
+6 -1
View File
@@ -1,4 +1,5 @@
using System.Windows.Controls;
using System;
using System.Windows.Controls;
namespace Daybreak.Services.ViewManagement
{
@@ -11,5 +12,9 @@ namespace Daybreak.Services.ViewManagement
void ShowView<T>(object dataContext)
where T : UserControl;
void ShowView(Type type);
void ShowView(Type type, object dataContext);
}
}
+24 -7
View File
@@ -1,6 +1,7 @@
using Slim;
using System;
using System.Extensions;
using System.Windows;
using System.Windows.Controls;
namespace Daybreak.Services.ViewManagement
@@ -32,17 +33,33 @@ namespace Daybreak.Services.ViewManagement
public void ShowView<T>() where T : UserControl
{
var view = this.serviceManager.GetService<T>();
this.container.Children.Clear();
this.container.Children.Add(view);
this.ShowViewInner(typeof(T), null);
}
public void ShowView<T>(object dataContext) where T : UserControl
{
var view = this.serviceManager.GetService<T>();
this.container.Children.Clear();
this.container.Children.Add(view);
view.DataContext = dataContext;
this.ShowViewInner(typeof(T), dataContext);
}
public void ShowView(Type type)
{
this.ShowViewInner(type, null);
}
public void ShowView(Type type, object dataContext)
{
this.ShowViewInner(type, dataContext);
}
private void ShowViewInner(Type viewType, object dataContext)
{
Application.Current.Dispatcher.Invoke(() =>
{
var view = this.serviceManager.GetService(viewType).As<UserControl>();
this.container.Children.Clear();
this.container.Children.Add(view);
view.DataContext = dataContext;
});
}
}
}
@@ -0,0 +1,12 @@
using System.Windows.Controls;
namespace Daybreak.Services.Privilege
{
public interface IPrivilegeManager
{
bool AdminPrivileges { get; }
void RequestAdminPrivileges<TCancelView>(string messageToUser, object dataContextOfCancelView = null)
where TCancelView : UserControl;
}
}
@@ -0,0 +1,34 @@
using Daybreak.Models;
using Daybreak.Services.Logging;
using Daybreak.Services.ViewManagement;
using Daybreak.Utils;
using Daybreak.Views;
using System.Extensions;
using System.Security.Principal;
using System.Windows.Controls;
namespace Daybreak.Services.Privilege
{
public sealed class PrivilegeManager : IPrivilegeManager
{
public bool AdminPrivileges => new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);
private readonly IViewManager viewManager;
private readonly ILogger logger;
public PrivilegeManager(
IViewManager viewManager,
ILogger logger)
{
this.logger = logger.ThrowIfNull(nameof(logger));
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
}
public void RequestAdminPrivileges<TCancelView>(string messageToUser, object dataContextOfCancelView = null)
where TCancelView : UserControl
{
this.logger.LogInformation("Requesting admin privileges");
this.viewManager.ShowView<RequestElevationView>(new ElevationRequest { View = typeof(TCancelView), DataContext = dataContextOfCancelView, MessageToUser = messageToUser });
}
}
}
@@ -21,6 +21,7 @@ namespace Daybreak.Services.Updater
{
public sealed class ApplicationUpdater : IApplicationUpdater
{
private const string LaunchActionName = "Launch_Daybreak";
private const string UpdateDesiredKey = "UpdateDesired";
private const string ExecutionPolicyKey = "ExecutionPolicy";
private const string UpdatedKey = "Updating";
@@ -32,13 +33,20 @@ namespace Daybreak.Services.Updater
private const string OutputPathTag = "{OUTPUTPATH}";
private const string ExecutionPolicyTag = "{EXECUTIONPOLICY}";
private const string ProcessIdTag = "{PROCESSID}";
private const string ExecutableNameTag = "{EXECUTABLE}";
private const string WorkingDirectoryTag = "{WORKINGDIRECTORY}";
private const string Url = "https://github.com/AlexMacocian/Daybreak/releases/latest";
private const string DownloadUrl = $"https://github.com/AlexMacocian/Daybreak/releases/download/v{VersionTag}/Daybreakv{VersionTag}.zip";
private const string GetExecutionPolicyCommand = "Get-ExecutionPolicy -Scope CurrentUser";
private const string SetExecutionPolicyCommand = $"Set-ExecutionPolicy {ExecutionPolicyTag} -Scope CurrentUser";
private const string WaitCommand = $"Wait-Process -Id {ProcessIdTag}";
private const string ExtractCommandTemplate = $"Expand-Archive -Path '{InputFileTag}' -DestinationPath '{OutputPathTag}' -Force";
private const string RunClientCommand = @".\Daybreak.exe";
private const string PrepareScheduledAction = $"$action = New-ScheduledTaskAction -Execute {ExecutableNameTag} -WorkingDirectory {WorkingDirectoryTag}";
private const string PrepareTriggerForAction = $"$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date)";
private const string RegisterScheduledAction = $"Register-ScheduledTask -Action $action -Trigger $trigger -TaskName {LaunchActionName} | Out-Null";
private const string LaunchScheduledAction = $"Start-ScheduledTask -TaskName {LaunchActionName}";
private const string SleepOneSecond = $"Start-Sleep -s 1";
private const string UnregisterScheduledAction = $"Unregister-ScheduledTask -TaskName {LaunchActionName} -Confirm:$false";
private const string RemoveTempFile = $"Remove-item {TempFile}";
private const string RemovePs1 = $"Remove-item {ExtractAndRunPs1}";
@@ -251,8 +259,15 @@ namespace Daybreak.Services.Updater
.Replace(InputFileTag, Path.GetFullPath(TempFile))
.Replace(OutputPathTag, Directory.GetCurrentDirectory()),
RemoveTempFile,
PrepareScheduledAction
.Replace(ExecutableNameTag, Process.GetCurrentProcess()?.MainModule?.FileName)
.Replace(WorkingDirectoryTag, Directory.GetCurrentDirectory()),
PrepareTriggerForAction,
RegisterScheduledAction,
LaunchScheduledAction,
SleepOneSecond,
UnregisterScheduledAction,
RemovePs1,
RunClientCommand
});
var process = new Process()
{
@@ -260,12 +275,10 @@ namespace Daybreak.Services.Updater
{
FileName = "powershell.exe",
Arguments = $@"{Directory.GetCurrentDirectory()}\{ExtractAndRunPs1}",
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardInput = true,
RedirectStandardOutput = true,
UseShellExecute = true,
WindowStyle = ProcessWindowStyle.Maximized,
WorkingDirectory = Directory.GetCurrentDirectory()
WorkingDirectory = Directory.GetCurrentDirectory(),
Verb = "runas"
},
};
this.logger.LogInformation("Created extractor script. Attempting to launch powershell");
+21 -1
View File
@@ -1,4 +1,5 @@
using Daybreak.Services.Logging;
using Daybreak.Services.Privilege;
using Daybreak.Services.Runtime;
using Daybreak.Services.Updater;
using Daybreak.Services.ViewManagement;
@@ -18,18 +19,32 @@ namespace Daybreak.Views
private readonly ILogger logger;
private readonly IViewManager viewManager;
private readonly IRuntimeStore runtimeStore;
private readonly IPrivilegeManager privilegeManager;
public AskUpdateView(
ILogger logger,
IViewManager viewManager,
IRuntimeStore runtimeStore)
IRuntimeStore runtimeStore,
IPrivilegeManager privilegeManager)
{
this.logger = logger.ThrowIfNull(nameof(logger));
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
this.runtimeStore = runtimeStore.ThrowIfNull(nameof(runtimeStore));
this.privilegeManager = privilegeManager.ThrowIfNull(nameof(privilegeManager));
this.InitializeComponent();
}
private bool CheckIfAdmin()
{
if (this.privilegeManager.AdminPrivileges is false)
{
this.privilegeManager.RequestAdminPrivileges<MainView>("Application needs to be in administrator mode in order to update.");
return false;
}
return true;
}
private void NoButton_Clicked(object sender, System.EventArgs e)
{
this.logger.LogInformation("User declined update");
@@ -41,6 +56,11 @@ namespace Daybreak.Views
{
this.logger.LogInformation("User accepted update");
this.runtimeStore.StoreValue(UpdateDesiredKey, true);
if (this.CheckIfAdmin() is false)
{
return;
}
this.viewManager.ShowView<UpdateView>();
}
}
@@ -91,6 +91,7 @@
<TextBlock Text="Multi-launch support" Foreground="White" FontSize="22" VerticalAlignment="Center" Margin="0, 0, 15, 0" Height="30"></TextBlock>
<TextBlock Text="GWToolbox startup delay (in ms)" Foreground="White" FontSize="22" VerticalAlignment="Center" Margin="0, 0, 15, 0" Height="30"></TextBlock>
<TextBlock Text="Detect build templates (in browser)" Foreground="White" FontSize="22" VerticalAlignment="Center" Margin="0, 0, 15, 0" Height="30"></TextBlock>
<TextBlock Text="Launch gw as current user" Foreground="White" FontSize="22" VerticalAlignment="Center" Margin="0, 0, 15, 0" Height="30"></TextBlock>
</StackPanel>
<StackPanel Grid.Column="1">
<ToggleButton IsChecked="{Binding ElementName=_this, Path=MultiLaunch, Mode=TwoWay}" Style="{StaticResource AnimatedSwitch}"
@@ -100,6 +101,8 @@
CommandManager.PreviewCanExecute="TextBox_DisallowPaste"></TextBox>
<ToggleButton IsChecked="{Binding ElementName=_this, Path=DynamicBuildLoading, Mode=TwoWay}" Style="{StaticResource AnimatedSwitch}"
Height="30" Width="60"></ToggleButton>
<ToggleButton IsChecked="{Binding ElementName=_this, Path=LaunchAsCurrentUser, Mode=TwoWay}" Style="{StaticResource AnimatedSwitch}"
Height="30" Width="60"></ToggleButton>
</StackPanel>
</Grid>
</Grid>
@@ -21,10 +21,17 @@ namespace Daybreak.Views
DependencyPropertyExtensions.Register<ExperimentalSettingsView, string>(nameof(GWToolboxLaunchDelay));
public static readonly DependencyProperty DynamicBuildLoadingProperty =
DependencyPropertyExtensions.Register<ExperimentalSettingsView, bool>(nameof(DynamicBuildLoading));
public static readonly DependencyProperty LaunchAsCurrentUserProperty =
DependencyPropertyExtensions.Register<ExperimentalSettingsView, bool>(nameof(LaunchAsCurrentUser));
private readonly IViewManager viewManager;
private readonly IConfigurationManager configurationManager;
public bool LaunchAsCurrentUser
{
get => this.GetTypedValue<bool>(LaunchAsCurrentUserProperty);
set => this.SetValue(LaunchAsCurrentUserProperty, value);
}
public bool MultiLaunch
{
get => this.GetTypedValue<bool>(MultiLaunchProperty);
@@ -57,6 +64,7 @@ namespace Daybreak.Views
this.MultiLaunch = config.ExperimentalFeatures.MultiLaunchSupport;
this.GWToolboxLaunchDelay = config.ExperimentalFeatures.ToolboxAutoLaunchDelay.ToString();
this.DynamicBuildLoading = config.ExperimentalFeatures.DynamicBuildLoading;
this.LaunchAsCurrentUser = config.ExperimentalFeatures.LaunchGuildwarsAsCurrentUser;
}
private void SaveExperimentalSettings()
@@ -64,6 +72,7 @@ namespace Daybreak.Views
var config = this.configurationManager.GetConfiguration();
config.ExperimentalFeatures.MultiLaunchSupport = this.MultiLaunch;
config.ExperimentalFeatures.DynamicBuildLoading = this.DynamicBuildLoading;
config.ExperimentalFeatures.LaunchGuildwarsAsCurrentUser = this.LaunchAsCurrentUser;
if (int.TryParse(this.GWToolboxLaunchDelay, out var gwToolboxLaunchDelay))
{
config.ExperimentalFeatures.ToolboxAutoLaunchDelay = gwToolboxLaunchDelay;
+28
View File
@@ -0,0 +1,28 @@
<UserControl x:Class="Daybreak.Views.RequestElevationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Daybreak.Views"
mc:Ignorable="d"
xmlns:controls="clr-namespace:Daybreak.Controls"
d:DesignHeight="450" d:DesignWidth="800">
<Grid VerticalAlignment="Center" HorizontalAlignment="Center" Background="White" MinHeight="200" MinWidth="400">
<StackPanel VerticalAlignment="Center" Orientation="Vertical">
<TextBlock Text="{Binding MessageToUser}" Margin="10, 0, 10, 0" Foreground="Black"
TextWrapping="Wrap" HorizontalAlignment="Center" FontSize="16"></TextBlock>
<TextBlock Text="Do you want to restart the application with administrator rights?" HorizontalAlignment="Center"
FontSize="16" Foreground="Black" Margin="10, 0, 10, 10"></TextBlock>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<controls:OpaqueButton Text="Yes" BackgroundOpacity="0.2" TransparentBackground="Gray" HorizontalAlignment="Center" Margin="10" Width="50" Height="25"
Clicked="YesButton_Clicked" Foreground="Black" FontSize="16"></controls:OpaqueButton>
<controls:OpaqueButton Text="No" BackgroundOpacity="0.2" TransparentBackground="Gray" HorizontalAlignment="Center" Margin="10" Width="50" Height="25"
Clicked="NoButton_Clicked" Foreground="Black" Grid.Column="1" FontSize="16"></controls:OpaqueButton>
</Grid>
</StackPanel>
</Grid>
</UserControl>
@@ -0,0 +1,51 @@
using Daybreak.Models;
using Daybreak.Services.ApplicationLauncher;
using Daybreak.Services.Logging;
using Daybreak.Services.Privilege;
using Daybreak.Services.ViewManagement;
using Daybreak.Utils;
using System.Extensions;
using System.Windows.Controls;
namespace Daybreak.Views
{
/// <summary>
/// Interaction logic for RequestElevationView.xaml
/// </summary>
public partial class RequestElevationView : UserControl
{
private readonly IApplicationLauncher applicationLauncher;
private readonly IViewManager viewManager;
private readonly ILogger logger;
public RequestElevationView(
IApplicationLauncher applicationLauncher,
IViewManager viewManager,
ILogger logger)
{
this.applicationLauncher = applicationLauncher.ThrowIfNull(nameof(applicationLauncher));
this.viewManager = viewManager.ThrowIfNull(nameof(viewManager));
this.logger = logger.ThrowIfNull(nameof(logger));
this.InitializeComponent();
}
private void YesButton_Clicked(object sender, System.EventArgs e)
{
this.applicationLauncher.RestartDaybreakAsAdmin();
}
private void NoButton_Clicked(object sender, System.EventArgs e)
{
if (this.DataContext is ElevationRequest elevationRequest)
{
this.logger.LogWarning($"Elevation request denied. Showing {elevationRequest.View} with {elevationRequest.DataContext}");
this.viewManager.ShowView(elevationRequest.View, elevationRequest.DataContext);
}
else
{
this.logger.LogWarning("Elevation request context is not set. Returning to home page");
this.viewManager.ShowView<MainView>();
}
}
}
}
-22
View File
@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="highestAvailable" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<application xmlns="urn:schemas-microsoft-com:asm.v3">
<windowsSettings>
<dpiAware xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">true</dpiAware>
</windowsSettings>
</application>
</assembly>