mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Improve UAC dialog
This commit is contained in:
parent
10d379f350
commit
484f91c52d
4 changed files with 243 additions and 4 deletions
|
|
@ -99,5 +99,6 @@
|
|||
<system:String x:Key="flowlauncher_plugin_program_run_failed">Unable to run {0}</system:String>
|
||||
<system:String x:Key="flowlauncher_plugin_program_user_account_control_title">User Account Control</system:String>
|
||||
<system:String x:Key="flowlauncher_plugin_program_user_account_control_subtitle">Do you want to allow this app to make changes to your device?</system:String>
|
||||
<system:String x:Key="flowlauncher_plugin_program_user_account_control_program_location">Program location: {0}</system:String>
|
||||
|
||||
</ResourceDictionary>
|
||||
|
|
|
|||
|
|
@ -221,10 +221,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
|||
if (elevated)
|
||||
{
|
||||
// Since we are already elevated, we need to create UAC dialog manually
|
||||
if (Main.Context.API.ShowMsgBox(
|
||||
Main.Context.API.GetTranslation("flowlauncher_plugin_program_user_account_control_subtitle"),
|
||||
Main.Context.API.GetTranslation("flowlauncher_plugin_program_user_account_control_title"),
|
||||
MessageBoxButton.YesNo) != MessageBoxResult.Yes)
|
||||
if (UACDialog.Show(IcoPath, Name, FullPath) != MessageBoxResult.Yes)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
154
Plugins/Flow.Launcher.Plugin.Program/UACDialog.xaml
Normal file
154
Plugins/Flow.Launcher.Plugin.Program/UACDialog.xaml
Normal file
|
|
@ -0,0 +1,154 @@
|
|||
<Window
|
||||
x:Class="Flow.Launcher.Plugin.Program.UACDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
x:Name="MessageBoxWindow"
|
||||
Width="420"
|
||||
Height="Auto"
|
||||
Background="{DynamicResource PopuBGColor}"
|
||||
Foreground="{DynamicResource PopupTextColor}"
|
||||
ResizeMode="NoResize"
|
||||
SizeToContent="Height"
|
||||
Topmost="True"
|
||||
WindowStartupLocation="CenterScreen"
|
||||
mc:Ignorable="d">
|
||||
<WindowChrome.WindowChrome>
|
||||
<WindowChrome CaptionHeight="32" ResizeBorderThickness="{x:Static SystemParameters.WindowResizeBorderThickness}" />
|
||||
</WindowChrome.WindowChrome>
|
||||
<Window.InputBindings>
|
||||
<KeyBinding Key="Escape" Command="Close" />
|
||||
</Window.InputBindings>
|
||||
<Window.CommandBindings>
|
||||
<CommandBinding Command="Close" Executed="KeyEsc_OnPress" />
|
||||
</Window.CommandBindings>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition />
|
||||
<RowDefinition MinHeight="68" />
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0">
|
||||
<StackPanel>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
Click="Button_Cancel"
|
||||
Style="{StaticResource TitleBarCloseButtonStyle}">
|
||||
<Path
|
||||
Width="46"
|
||||
Height="32"
|
||||
Data="M 18,11 27,20 M 18,20 27,11"
|
||||
Stroke="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Button}}}"
|
||||
StrokeThickness="1">
|
||||
<Path.Style>
|
||||
<Style TargetType="Path">
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding Path=IsActive, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" Value="False">
|
||||
<Setter Property="Opacity" Value="0.5" />
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Path.Style>
|
||||
</Path>
|
||||
</Button>
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
<Grid Grid.Row="1" Margin="30 0 30 24">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid Grid.Row="0" Margin="0 0 0 12">
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
MaxWidth="400"
|
||||
Margin="0 0 26 0"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="Segoe UI"
|
||||
FontSize="20"
|
||||
FontWeight="SemiBold"
|
||||
Text="{DynamicResource flowlauncher_plugin_program_user_account_control_title}"
|
||||
TextAlignment="Left"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
MaxWidth="400"
|
||||
Margin="0 0 26 0"
|
||||
HorizontalAlignment="Stretch"
|
||||
FontSize="14"
|
||||
Text="{DynamicResource flowlauncher_plugin_program_user_account_control_subtitle}"
|
||||
TextAlignment="Left"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="2" Margin="30 0 30 16">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Image
|
||||
Name="Img"
|
||||
Grid.Column="0"
|
||||
Width="18"
|
||||
Height="18"
|
||||
Margin="0 0 10 0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
RenderOptions.BitmapScalingMode="Fant"
|
||||
Stretch="UniformToFill" />
|
||||
<TextBlock
|
||||
x:Name="AppName"
|
||||
Grid.Column="1"
|
||||
MaxWidth="400"
|
||||
Margin="0 0 26 0"
|
||||
HorizontalAlignment="Stretch"
|
||||
FontSize="16"
|
||||
TextAlignment="Left"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
<Grid Grid.Row="3" Margin="30 0 30 24">
|
||||
<TextBlock
|
||||
x:Name="ProgramLocation"
|
||||
Grid.Column="1"
|
||||
MaxWidth="400"
|
||||
Margin="0 0 26 0"
|
||||
HorizontalAlignment="Stretch"
|
||||
FontSize="14"
|
||||
TextAlignment="Left"
|
||||
TextWrapping="Wrap" />
|
||||
</Grid>
|
||||
<Border
|
||||
Grid.Row="4"
|
||||
Margin="0 0 0 0"
|
||||
Background="{DynamicResource PopupButtonAreaBGColor}"
|
||||
BorderBrush="{DynamicResource PopupButtonAreaBorderColor}"
|
||||
BorderThickness="0 1 0 0">
|
||||
<WrapPanel
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Orientation="Horizontal">
|
||||
<Button
|
||||
x:Name="btnYes"
|
||||
MinWidth="120"
|
||||
Margin="5 0 5 0"
|
||||
Click="Button_Click"
|
||||
Content="{DynamicResource commonYes}" />
|
||||
<Button
|
||||
x:Name="btnNo"
|
||||
MinWidth="120"
|
||||
Margin="5 0 5 0"
|
||||
Click="Button_Click"
|
||||
Content="{DynamicResource commonNo}" />
|
||||
</WrapPanel>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Window>
|
||||
87
Plugins/Flow.Launcher.Plugin.Program/UACDialog.xaml.cs
Normal file
87
Plugins/Flow.Launcher.Plugin.Program/UACDialog.xaml.cs
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace Flow.Launcher.Plugin.Program
|
||||
{
|
||||
public partial class UACDialog : Window
|
||||
{
|
||||
private static readonly string ClassName = nameof(UACDialog);
|
||||
|
||||
private static UACDialog msgBox;
|
||||
private static MessageBoxResult _result = MessageBoxResult.None;
|
||||
|
||||
private UACDialog()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public static MessageBoxResult Show(string iconPath, string appName, string fullPath)
|
||||
{
|
||||
if (!Application.Current.Dispatcher.CheckAccess())
|
||||
{
|
||||
return Application.Current.Dispatcher.Invoke(() => Show(iconPath, appName, fullPath));
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
msgBox = new UACDialog
|
||||
{
|
||||
Title = Main.Context.API.GetTranslation("flowlauncher_plugin_program_user_account_control_title")
|
||||
};
|
||||
|
||||
// Set icon & app name & program location
|
||||
_ = msgBox.SetImageAsync(iconPath);
|
||||
msgBox.AppName.Text = appName;
|
||||
msgBox.ProgramLocation.Text = string.Format(
|
||||
Main.Context.API.GetTranslation("flowlauncher_plugin_program_user_account_control_program_location"),
|
||||
fullPath);
|
||||
|
||||
// Focus No by default
|
||||
msgBox.btnNo.Focus();
|
||||
_result = MessageBoxResult.No;
|
||||
|
||||
msgBox.ShowDialog();
|
||||
return _result;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Main.Context.API.LogError(ClassName, $"An error occurred: {e.Message}");
|
||||
msgBox = null;
|
||||
return MessageBoxResult.None;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task SetImageAsync(string imagePath)
|
||||
{
|
||||
var imageSource = await Main.Context.API.LoadImageAsync(imagePath);
|
||||
Img.Source = imageSource;
|
||||
}
|
||||
|
||||
private void KeyEsc_OnPress(object sender, ExecutedRoutedEventArgs e)
|
||||
{
|
||||
DialogResult = false;
|
||||
Close();
|
||||
}
|
||||
|
||||
private void Button_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender == btnYes)
|
||||
_result = MessageBoxResult.Yes;
|
||||
else if (sender == btnNo)
|
||||
_result = MessageBoxResult.No;
|
||||
else
|
||||
_result = MessageBoxResult.None;
|
||||
msgBox.Close();
|
||||
msgBox = null;
|
||||
}
|
||||
|
||||
private void Button_Cancel(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_result = MessageBoxResult.Cancel;
|
||||
msgBox.Close();
|
||||
msgBox = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue