3 Commits
Author SHA1 Message Date
ded_ikar 0c2212cde9 Add dark custom title bar with WindowChrome 2026-06-08 20:31:38 +05:00
Your Name 793076b948 initial 2026-06-06 00:37:49 +05:00
ded_ikar e7ea83daa0 fix QoS 2026-05-04 01:50:35 +05:00
13 changed files with 531 additions and 110 deletions
BIN
View File
Binary file not shown.
+60 -7
View File
@@ -108,7 +108,7 @@ namespace QoSManager.Services
private string GetPolicyStore() private string GetPolicyStore()
{ {
return $"GPO:{Environment.MachineName}"; return "localhost";
} }
private static string EscapePowerShellString(string value) private static string EscapePowerShellString(string value)
@@ -251,7 +251,7 @@ namespace QoSManager.Services
var escapedName = EscapePowerShellString(policy.Name); var escapedName = EscapePowerShellString(policy.Name);
var escapedProcess = EscapePowerShellString(policy.Process); var escapedProcess = EscapePowerShellString(policy.Process);
var escapedStore = EscapePowerShellString(GetPolicyStore()); var escapedStore = EscapePowerShellString(GetPolicyStore());
var command = $"New-NetQosPolicy -Name '{escapedName}' -AppPathNameMatchCondition '{escapedProcess}' -DSCPAction {policy.DSCP} -PolicyStore '{escapedStore}'"; var command = $"New-NetQosPolicy -Name '{escapedName}' -AppPathNameMatchCondition '{escapedProcess}' -DSCPAction {policy.DSCP} -PolicyStore '{escapedStore}' -NetworkProfile All";
var encodedCommand = Convert.ToBase64String(Encoding.Unicode.GetBytes(command)); var encodedCommand = Convert.ToBase64String(Encoding.Unicode.GetBytes(command));
var startInfo = new ProcessStartInfo var startInfo = new ProcessStartInfo
@@ -291,7 +291,7 @@ namespace QoSManager.Services
{ {
try try
{ {
_logger.LogInformation("Refreshing Group Policy to synchronize with gpedit.msc"); LogInformation("Refreshing Group Policy to synchronize with gpedit.msc");
var startInfo = new ProcessStartInfo var startInfo = new ProcessStartInfo
{ {
FileName = "cmd.exe", FileName = "cmd.exe",
@@ -310,19 +310,19 @@ namespace QoSManager.Services
var output = process.StandardOutput.ReadToEnd(); var output = process.StandardOutput.ReadToEnd();
var error = process.StandardError.ReadToEnd(); var error = process.StandardError.ReadToEnd();
_logger.LogInformation($"Gpupdate output: {output}"); LogInformation($"Gpupdate output: {output}");
if (!string.IsNullOrEmpty(error)) if (!string.IsNullOrEmpty(error))
{ {
_logger.LogInformation($"Gpupdate error: {error}"); LogInformation($"Gpupdate error: {error}");
} }
if (process.ExitCode == 0) if (process.ExitCode == 0)
{ {
_logger.LogInformation("Group Policy updated successfully"); LogInformation("Group Policy updated successfully");
} }
else else
{ {
_logger.LogInformation($"Group Policy update returned exit code: {process.ExitCode}"); LogInformation($"Group Policy update returned exit code: {process.ExitCode}");
} }
} }
} }
@@ -332,6 +332,59 @@ namespace QoSManager.Services
} }
} }
public void RefreshQoSPolicies()
{
try
{
if (_loggingEnabled)
{
LogInformation("Force refreshing QoS policies to ensure they apply after reboot");
}
// Force update Group Policy
RefreshGroupPolicy();
// Restart QoS service to ensure policies apply
var startInfo = new ProcessStartInfo
{
FileName = "cmd.exe",
Arguments = "/c sc query QWAVE | find \"STATE\" && net stop QWAVE && net start QWAVE || net start QWAVE",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
StandardOutputEncoding = System.Text.Encoding.UTF8,
StandardErrorEncoding = System.Text.Encoding.UTF8
};
using (var process = Process.Start(startInfo))
{
process.WaitForExit();
var output = process.StandardOutput.ReadToEnd();
var error = process.StandardError.ReadToEnd();
LogInformation($"QoS service restart output: {output}");
if (!string.IsNullOrEmpty(error))
{
LogInformation($"QoS service restart error: {error}");
}
if (process.ExitCode == 0)
{
LogInformation("QoS service restarted successfully");
}
else
{
LogInformation($"QoS service restart returned exit code: {process.ExitCode}");
}
}
}
catch (Exception ex)
{
_logger.LogError(ex, "Error refreshing QoS policies");
}
}
public void DeletePolicy(string policyName, bool autoRefreshGPO = true) public void DeletePolicy(string policyName, bool autoRefreshGPO = true)
{ {
try try
+57
View File
@@ -83,6 +83,63 @@
<Setter Property="Foreground" Value="White"/> <Setter Property="Foreground" Value="White"/>
</Style> </Style>
<!-- Стиль для кастомного заголовка окна -->
<Style x:Key="TitleBar" TargetType="Border">
<Setter Property="Background" Value="#2D2D2D"/>
<Setter Property="Height" Value="30"/>
<Setter Property="BorderBrush" Value="#444444"/>
<Setter Property="BorderThickness" Value="0,0,0,1"/>
<Setter Property="CornerRadius" Value="8,8,0,0"/>
</Style>
<Style x:Key="TitleBarText" TargetType="TextBlock">
<Setter Property="Foreground" Value="#CCCCCC"/>
<Setter Property="FontSize" Value="12"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="12,0,0,0"/>
</Style>
<Style x:Key="TitleBarButton" TargetType="Button">
<Setter Property="Width" Value="46"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}">
<TextBlock Text="{TemplateBinding Content}"
FontFamily="Segoe MDL2 Assets"
FontSize="10"
HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#3C3C3C"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#2A2A2A"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="TitleBarCloseButton" TargetType="Button" BasedOn="{StaticResource TitleBarButton}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#E81123"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#F1707A"/>
</Trigger>
</Style.Triggers>
</Style>
<!-- Стиль для MessageBox buttons --> <!-- Стиль для MessageBox buttons -->
<Style TargetType="Button" x:Key="{x:Type Button}"> <Style TargetType="Button" x:Key="{x:Type Button}">
<Setter Property="Background" Value="#3C3C3C"/> <Setter Property="Background" Value="#3C3C3C"/>
+33 -6
View File
@@ -3,23 +3,48 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="QoS Manager" Title="QoS Manager"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
WindowStyle="None"
ResizeMode="NoResize" ResizeMode="NoResize"
SizeToContent="WidthAndHeight" SizeToContent="WidthAndHeight"
Background="#2D2D2D" Background="#2D2D2D"
WindowStyle="SingleBorderWindow"
BorderBrush="#444444" BorderBrush="#444444"
BorderThickness="1" BorderThickness="1"
FontFamily="Segoe UI" FontFamily="Segoe UI"
MinWidth="300" MinWidth="300"
MaxWidth="500"> MaxWidth="500">
<Grid Margin="20"> <WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" GlassFrameThickness="0" ResizeBorderThickness="0" UseAeroCaptionButtons="False"/>
</WindowChrome.WindowChrome>
<Border BorderBrush="#555555" BorderThickness="1" CornerRadius="8" Background="#2D2D2D">
<Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="30"/>
<RowDefinition Height="20"/> <RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Title Bar -->
<Border Grid.Row="0" Style="{StaticResource TitleBar}"
MouseLeftButtonDown="TitleBar_MouseLeftButtonDown">
<Grid>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}"
Style="{StaticResource TitleBarText}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="CloseButton" Style="{StaticResource TitleBarCloseButton}"
Click="CloseButton_Click" Content="&#xE8BB;"/>
</StackPanel>
</Grid>
</Border>
<!-- Content -->
<Grid Grid.Row="1" Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="20"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Сообщение --> <!-- Сообщение -->
<TextBlock x:Name="MessageTextBlock" <TextBlock x:Name="MessageTextBlock"
Grid.Row="0" Grid.Row="0"
@@ -70,5 +95,7 @@
Click="NoButton_Click" Click="NoButton_Click"
Visibility="Collapsed"/> Visibility="Collapsed"/>
</StackPanel> </StackPanel>
</Grid> </Grid>
</Grid>
</Border>
</Window> </Window>
+15
View File
@@ -1,4 +1,5 @@
using System.Windows; using System.Windows;
using System.Windows.Input;
namespace QoSManager.Views namespace QoSManager.Views
{ {
@@ -83,5 +84,19 @@ namespace QoSManager.Views
Result = MessageBoxResult.No; Result = MessageBoxResult.No;
Close(); Close();
} }
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
DragMove();
}
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Result = MessageBoxResult.Cancel;
Close();
}
} }
} }
+113 -64
View File
@@ -5,77 +5,108 @@
Height="600" Width="900" Height="600" Width="900"
MinHeight="400" MinWidth="600" MinHeight="400" MinWidth="600"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
WindowStyle="None"
Background="#1E1E1E"> Background="#1E1E1E">
<Grid Margin="20"> <WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" GlassFrameThickness="0" ResizeBorderThickness="5" UseAeroCaptionButtons="False"/>
</WindowChrome.WindowChrome>
<Border BorderBrush="#555555" BorderThickness="1" CornerRadius="8" Background="#1E1E1E">
<Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="30"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Заголовок --> <!-- Title Bar -->
<StackPanel Grid.Row="0" Margin="0,0,0,20"> <Border Grid.Row="0" Style="{StaticResource TitleBar}"
MouseLeftButtonDown="TitleBar_MouseLeftButtonDown">
<Grid> <Grid>
<Grid.ColumnDefinitions> <TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}"
<ColumnDefinition Width="*"/> Style="{StaticResource TitleBarText}"/>
<ColumnDefinition Width="Auto"/> <StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
</Grid.ColumnDefinitions> <Button x:Name="MinimizeButton" Style="{StaticResource TitleBarButton}"
Click="MinimizeButton_Click" Content="&#xE921;"/>
<StackPanel Grid.Column="0"> <Button x:Name="MaximizeButton" Style="{StaticResource TitleBarButton}"
<TextBlock Text="Управление QoS-политиками Windows" Click="MaximizeButton_Click" Content="&#xE922;"/>
FontSize="18" <Button x:Name="CloseButton" Style="{StaticResource TitleBarCloseButton}"
FontWeight="SemiBold" Click="CloseButton_Click" Content="&#xE8BB;"/>
Foreground="White"/>
<TextBlock Text="Добавляйте, удаляйте и просматривайте политики для отдельных процессов."
FontSize="12"
Foreground="#A0A0A0"
Margin="0,5,0,10"/>
</StackPanel>
<StackPanel Grid.Column="1"
Orientation="Horizontal"
VerticalAlignment="Top"
Margin="20,0,0,0">
<CheckBox x:Name="LoggingCheckBox"
Content="Вести логи"
Width="120"
Height="30"
Foreground="White"
VerticalContentAlignment="Center"/>
</StackPanel> </StackPanel>
</Grid> </Grid>
</StackPanel> </Border>
<!-- Content -->
<!-- Таблица политик --> <Grid Grid.Row="1" Margin="20">
<DataGrid x:Name="PoliciesDataGrid" <Grid.RowDefinitions>
Grid.Row="1" <RowDefinition Height="Auto"/>
AutoGenerateColumns="False" <RowDefinition Height="*"/>
CanUserAddRows="False" <RowDefinition Height="Auto"/>
CanUserDeleteRows="False" <RowDefinition Height="Auto"/>
CanUserReorderColumns="False" </Grid.RowDefinitions>
CanUserResizeRows="False"
IsReadOnly="True" <!-- Заголовок -->
BeginningEdit="PoliciesDataGrid_BeginningEdit" <StackPanel Grid.Row="0" Margin="0,0,0,20">
CellEditEnding="PoliciesDataGrid_CellEditEnding" <Grid>
GridLinesVisibility="All" <Grid.ColumnDefinitions>
HorizontalGridLinesBrush="#333333" <ColumnDefinition Width="*"/>
VerticalGridLinesBrush="#555555" <ColumnDefinition Width="Auto"/>
Background="#2D2D2D" </Grid.ColumnDefinitions>
Foreground="White"
BorderBrush="#444444" <StackPanel Grid.Column="0">
BorderThickness="1" <TextBlock Text="Управление QoS-политиками Windows"
HeadersVisibility="Column" FontSize="18"
SelectionMode="Single" FontWeight="SemiBold"
AlternatingRowBackground="#252525" Foreground="White"/>
RowHeight="30" <TextBlock Text="Создавайте и управляйте QoS-политиками для приоритизации сетевого трафика"
MinRowHeight="25" FontSize="12"
VirtualizingPanel.IsVirtualizing="True" Foreground="#CCCCCC"
VirtualizingPanel.VirtualizationMode="Recycling" Margin="0,5,0,0"/>
ScrollViewer.CanContentScroll="True" </StackPanel>
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto"> <StackPanel Grid.Column="1"
Orientation="Horizontal"
VerticalAlignment="Top">
<TextBlock Text="Статус: "
FontSize="12"
Foreground="#CCCCCC"
VerticalAlignment="Center"/>
<TextBlock Text="Активно"
FontSize="12"
FontWeight="SemiBold"
Foreground="#4CAF50"
VerticalAlignment="Center"/>
</StackPanel>
</Grid>
</StackPanel>
<!-- DataGrid -->
<DataGrid x:Name="PoliciesDataGrid"
Grid.Row="1"
AutoGenerateColumns="False"
CanUserAddRows="False"
CanUserDeleteRows="False"
CanUserReorderColumns="False"
CanUserResizeColumns="True"
CanUserResizeRows="False"
CanUserSortColumns="True"
GridLinesVisibility="Horizontal"
HorizontalGridLinesBrush="#3C3C3C"
VerticalGridLinesBrush="Transparent"
Background="#1E1E1E"
Foreground="White"
BorderBrush="#3C3C3C"
BorderThickness="1"
HeadersVisibility="Column"
SelectionMode="Single"
AlternatingRowBackground="#252525"
RowHeight="30"
MinRowHeight="25"
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
ScrollViewer.CanContentScroll="True"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
ScrollViewer.VerticalScrollBarVisibility="Auto">
<DataGrid.ColumnHeaderStyle> <DataGrid.ColumnHeaderStyle>
<Style TargetType="DataGridColumnHeader"> <Style TargetType="DataGridColumnHeader">
@@ -129,7 +160,7 @@
Binding="{Binding Name}" Binding="{Binding Name}"
Width="180" Width="180"
IsReadOnly="True"/> IsReadOnly="True"/>
<DataGridTextColumn Header="Процесс / путь" <DataGridTextColumn Header="Процесс"
Binding="{Binding Process}" Binding="{Binding Process}"
Width="*" Width="*"
IsReadOnly="True"/> IsReadOnly="True"/>
@@ -145,8 +176,23 @@
</DataGrid> </DataGrid>
<!-- Настройки -->
<StackPanel x:Name="SettingsPanel"
Grid.Row="2"
Orientation="Horizontal"
HorizontalAlignment="Left"
Margin="0,20,0,10">
<CheckBox x:Name="LoggingCheckBox"
Content="Вести логи"
Width="120"
Height="30"
Foreground="White"
VerticalContentAlignment="Center"/>
</StackPanel>
<!-- Кнопки --> <!-- Кнопки -->
<StackPanel Grid.Row="2" <StackPanel Grid.Row="3"
Orientation="Horizontal" Orientation="Horizontal"
HorizontalAlignment="Right" HorizontalAlignment="Right"
Margin="0,20,0,0"> Margin="0,20,0,0">
@@ -172,6 +218,7 @@
Margin="0,0,10,0" Margin="0,0,10,0"
Style="{StaticResource DarkButtonStyle}"/> Style="{StaticResource DarkButtonStyle}"/>
<Button x:Name="LogButton" <Button x:Name="LogButton"
Content="Открыть лог" Content="Открыть лог"
Width="100" Width="100"
@@ -185,5 +232,7 @@
Height="35" Height="35"
Style="{StaticResource DarkButtonStyle}"/> Style="{StaticResource DarkButtonStyle}"/>
</StackPanel> </StackPanel>
</Grid> </Grid>
</Grid>
</Border>
</Window> </Window>
+96 -5
View File
@@ -1,9 +1,15 @@
using System; using System;
using System.Collections;
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Data;
using QoSManager.Models; using QoSManager.Models;
using QoSManager.Services; using QoSManager.Services;
@@ -14,7 +20,8 @@ namespace QoSManager.Views
private readonly QoSService _qosService; private readonly QoSService _qosService;
private readonly LoggingService _loggingService; private readonly LoggingService _loggingService;
private readonly ObservableCollection<QoSPolicy> _policies; private readonly ObservableCollection<QoSPolicy> _policies;
private bool _loggingEnabled = true; private bool _loggingEnabled = false;
private bool _isInitialized = false;
public MainWindow() public MainWindow()
{ {
@@ -41,9 +48,22 @@ namespace QoSManager.Views
// Initialize checkbox state // Initialize checkbox state
LoggingCheckBox.IsChecked = _loggingEnabled; LoggingCheckBox.IsChecked = _loggingEnabled;
// Hide settings panel initially and show it after UI is fully loaded
SettingsPanel.Visibility = Visibility.Collapsed;
// Don't log startup - let user enable logging manually if needed // Don't log startup - let user enable logging manually if needed
LoadPolicies(); LoadPolicies();
// Show settings panel and mark initialization as complete after UI loads
Dispatcher.BeginInvoke(() => {
// Always show checkboxes panel with current settings state
SettingsPanel.Visibility = Visibility.Visible;
_isInitialized = true;
// Auto-refresh QoS policies disabled on startup to prevent unwanted behavior
// User must manually enable auto-refresh if needed
});
} }
public ObservableCollection<QoSPolicy> Policies => _policies; public ObservableCollection<QoSPolicy> Policies => _policies;
@@ -65,7 +85,7 @@ namespace QoSManager.Views
{ {
try try
{ {
// Load logging preference from Properties.Settings // Load preferences from Properties.Settings
_loggingEnabled = Properties.Settings.Default.EnableLogging; _loggingEnabled = Properties.Settings.Default.EnableLogging;
} }
catch catch
@@ -78,7 +98,7 @@ namespace QoSManager.Views
{ {
try try
{ {
// Save logging preference to Properties.Settings // Save preferences to Properties.Settings
Properties.Settings.Default.EnableLogging = _loggingEnabled; Properties.Settings.Default.EnableLogging = _loggingEnabled;
Properties.Settings.Default.Save(); Properties.Settings.Default.Save();
} }
@@ -215,6 +235,40 @@ namespace QoSManager.Views
LoadPolicies(); LoadPolicies();
} }
private void RefreshPoliciesButton_Click(object sender, RoutedEventArgs e)
{
try
{
_loggingService.LogInformation("Force refreshing QoS policies by user request", _loggingEnabled);
// Show progress message
CustomMessageBox.Show(
"Выполняется принудительное перечитывание QoS политик...\n\n" +
"Это может занять несколько секунд.\n" +
"После обновления может потребоваться перезапуск приложений.",
"Перечитывание политик", MessageBoxButton.OK, MessageBoxImage.Information);
// Force refresh QoS policies
_qosService.RefreshQoSPolicies();
// Reload policies list
LoadPolicies();
_loggingService.LogInformation("QoS policies refreshed successfully", _loggingEnabled);
// Show success message
CustomMessageBox.Show(
"QoS политики перечитаны",
"Успешно", MessageBoxButton.OK, MessageBoxImage.Information);
}
catch (Exception ex)
{
_loggingService.LogError($"Error refreshing QoS policies: {ex.Message}", _loggingEnabled);
CustomMessageBox.Show($"Ошибка при перечитывании QoS политик:\n\n{ex.Message}",
"Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void LogButton_Click(object sender, RoutedEventArgs e) private void LogButton_Click(object sender, RoutedEventArgs e)
{ {
try try
@@ -235,23 +289,60 @@ namespace QoSManager.Views
_loggingEnabled = true; _loggingEnabled = true;
_qosService.SetLoggingEnabled(_loggingEnabled); _qosService.SetLoggingEnabled(_loggingEnabled);
((App)Application.Current).SetLoggingEnabled(_loggingEnabled); ((App)Application.Current).SetLoggingEnabled(_loggingEnabled);
_loggingService.LogInformation("Логирование включено", _loggingEnabled); if (_isInitialized)
{
_loggingService.LogInformation("Логирование включено", true);
}
} }
private void LoggingCheckBox_Unchecked(object sender, RoutedEventArgs e) private void LoggingCheckBox_Unchecked(object sender, RoutedEventArgs e)
{ {
// Log the disable action before actually disabling // Log the disable action before actually disabling
_loggingService.LogInformation("Логирование отключено пользователем", _loggingEnabled); if (_isInitialized && _loggingEnabled)
{
_loggingService.LogInformation("Логирование отключено пользователем", true);
}
_loggingEnabled = false; _loggingEnabled = false;
_qosService.SetLoggingEnabled(_loggingEnabled); _qosService.SetLoggingEnabled(_loggingEnabled);
((App)Application.Current).SetLoggingEnabled(_loggingEnabled); ((App)Application.Current).SetLoggingEnabled(_loggingEnabled);
} }
private void ExitButton_Click(object sender, RoutedEventArgs e) private void ExitButton_Click(object sender, RoutedEventArgs e)
{ {
Close(); Close();
} }
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
DragMove();
}
}
private void MinimizeButton_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Minimized;
}
private void MaximizeButton_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState == WindowState.Maximized ? WindowState.Normal : WindowState.Maximized;
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Close();
}
protected override void OnStateChanged(EventArgs e)
{
base.OnStateChanged(e);
if (MaximizeButton != null)
MaximizeButton.Content = WindowState == WindowState.Maximized ? "\uE923" : "\uE922";
}
protected override void OnClosed(EventArgs e) protected override void OnClosed(EventArgs e)
{ {
SaveSettings(); SaveSettings();
+37 -9
View File
@@ -1,23 +1,49 @@
<Window x:Class="QoSManager.Views.PolicyEditWindow" <Window x:Class="QoSManager.Views.PolicyEditWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Создание QoS-политики" Title="Создание QoS-политики"
Height="320" Width="500" Height="320" Width="500"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
WindowStyle="None"
Background="#1E1E1E" Background="#1E1E1E"
ResizeMode="NoResize"> ResizeMode="NoResize">
<Grid Margin="20"> <WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" GlassFrameThickness="0" ResizeBorderThickness="0" UseAeroCaptionButtons="False"/>
</WindowChrome.WindowChrome>
<Border BorderBrush="#555555" BorderThickness="1" CornerRadius="8" Background="#1E1E1E">
<Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="30"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.ColumnDefinitions> <!-- Title Bar -->
<Border Grid.Row="0" Style="{StaticResource TitleBar}"
MouseLeftButtonDown="TitleBar_MouseLeftButtonDown">
<Grid>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}"
Style="{StaticResource TitleBarText}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="CloseButton" Style="{StaticResource TitleBarCloseButton}"
Click="CloseButton_Click" Content="&#xE8BB;"/>
</StackPanel>
</Grid>
</Border>
<!-- Content -->
<Grid Grid.Row="1" Margin="20">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/> <ColumnDefinition Width="120"/>
<ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
@@ -128,5 +154,7 @@
Height="35" Height="35"
Style="{StaticResource DarkButtonStyle}"/> Style="{StaticResource DarkButtonStyle}"/>
</StackPanel> </StackPanel>
</Grid> </Grid>
</Grid>
</Border>
</Window> </Window>
+15 -1
View File
@@ -1,6 +1,7 @@
using System; using System;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Win32; using Microsoft.Win32;
using QoSManager.Models; using QoSManager.Models;
using QoSManager.Services; using QoSManager.Services;
@@ -134,7 +135,7 @@ namespace QoSManager.Views
if (string.IsNullOrWhiteSpace(ProcessTextBox.Text)) if (string.IsNullOrWhiteSpace(ProcessTextBox.Text))
{ {
CustomMessageBox.Show("Укажите процесс или путь к исполняемому файлу.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error); CustomMessageBox.Show("Укажите имя процесса.", "Ошибка", MessageBoxButton.OK, MessageBoxImage.Error);
ProcessTextBox.Focus(); ProcessTextBox.Focus();
return false; return false;
} }
@@ -184,5 +185,18 @@ namespace QoSManager.Views
DSCP = dscpValue DSCP = dscpValue
}; };
} }
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
DragMove();
}
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Close();
}
} }
} }
+36 -12
View File
@@ -4,26 +4,48 @@
Title="Выбор процесса" Title="Выбор процесса"
Height="600" Width="800" Height="600" Width="800"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
WindowStyle="None"
ResizeMode="CanResize" ResizeMode="CanResize"
Background="#2b2b2b" Background="#2b2b2b"
TextElement.Foreground="White"> TextElement.Foreground="White">
<Window.Resources> <WindowChrome.WindowChrome>
<Style TargetType="Window"> <WindowChrome CaptionHeight="0" GlassFrameThickness="0" ResizeBorderThickness="5" UseAeroCaptionButtons="False"/>
<Setter Property="Foreground" Value="White"/> </WindowChrome.WindowChrome>
</Style>
</Window.Resources>
<Grid Margin="10"> <Border BorderBrush="#555555" BorderThickness="1" CornerRadius="8" Background="#2b2b2b">
<Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="30"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Выберите запущенный процесс:" <!-- Title Bar -->
FontSize="14" FontWeight="Bold" <Border Grid.Row="0" Style="{StaticResource TitleBar}"
Foreground="White" Margin="0,0,0,10"/> MouseLeftButtonDown="TitleBar_MouseLeftButtonDown">
<Grid>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}"
Style="{StaticResource TitleBarText}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="MinimizeButton" Style="{StaticResource TitleBarButton}"
Click="MinimizeButton_Click" Content="&#xE921;"/>
<Button x:Name="CloseButton" Style="{StaticResource TitleBarCloseButton}"
Click="CloseButton_Click" Content="&#xE8BB;"/>
</StackPanel>
</Grid>
</Border>
<!-- Content -->
<Grid Grid.Row="1" Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="Выберите запущенный процесс:"
FontSize="14" FontWeight="Bold"
Foreground="White" Margin="0,0,0,10"/>
<DataGrid x:Name="ProcessesDataGrid" Grid.Row="1" <DataGrid x:Name="ProcessesDataGrid" Grid.Row="1"
AutoGenerateColumns="False" AutoGenerateColumns="False"
@@ -63,5 +85,7 @@
Background="#4a4a4a" Foreground="White" Background="#4a4a4a" Foreground="White"
BorderBrush="#6a6a6a" Margin="0,0,10,0" Click="CancelButton_Click"/> BorderBrush="#6a6a6a" Margin="0,0,10,0" Click="CancelButton_Click"/>
</StackPanel> </StackPanel>
</Grid> </Grid>
</Grid>
</Border>
</Window> </Window>
+22 -2
View File
@@ -4,6 +4,7 @@ using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using System.Windows.Input;
using QoSManager.Models; using QoSManager.Models;
namespace QoSManager.Views namespace QoSManager.Views
@@ -30,7 +31,7 @@ namespace QoSManager.Views
var processInfo = new ProcessInfo var processInfo = new ProcessInfo
{ {
Id = process.Id, Id = process.Id,
Name = process.ProcessName, Name = (process.ProcessName + ".exe").ToLower(),
Path = process.MainModule?.FileName ?? "Unknown" Path = process.MainModule?.FileName ?? "Unknown"
}; };
@@ -57,7 +58,7 @@ namespace QoSManager.Views
{ {
if (ProcessesDataGrid.SelectedItem is ProcessInfo selectedProcess) if (ProcessesDataGrid.SelectedItem is ProcessInfo selectedProcess)
{ {
SelectedProcess = selectedProcess.Path; SelectedProcess = selectedProcess.Name;
DialogResult = true; DialogResult = true;
Close(); Close();
} }
@@ -68,5 +69,24 @@ namespace QoSManager.Views
DialogResult = false; DialogResult = false;
Close(); Close();
} }
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
DragMove();
}
}
private void MinimizeButton_Click(object sender, RoutedEventArgs e)
{
WindowState = WindowState.Minimized;
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
Close();
}
} }
} }
+32 -4
View File
@@ -3,16 +3,42 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Неподдерживаемая версия Windows" Height="520" Width="580" Title="Неподдерживаемая версия Windows" Height="520" Width="580"
WindowStartupLocation="CenterScreen" WindowStartupLocation="CenterScreen"
WindowStyle="None"
ResizeMode="NoResize" ResizeMode="NoResize"
Background="#2D2D30"> Background="#2D2D30">
<Grid Margin="25"> <WindowChrome.WindowChrome>
<WindowChrome CaptionHeight="0" GlassFrameThickness="0" ResizeBorderThickness="0" UseAeroCaptionButtons="False"/>
</WindowChrome.WindowChrome>
<Border BorderBrush="#555555" BorderThickness="1" CornerRadius="8" Background="#2D2D30">
<Grid>
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="Auto"/> <RowDefinition Height="30"/>
<RowDefinition Height="*"/> <RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions> </Grid.RowDefinitions>
<!-- Title Bar -->
<Border Grid.Row="0" Style="{StaticResource TitleBar}"
MouseLeftButtonDown="TitleBar_MouseLeftButtonDown">
<Grid>
<TextBlock Text="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}"
Style="{StaticResource TitleBarText}"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button x:Name="CloseButton" Style="{StaticResource TitleBarCloseButton}"
Click="CloseButton_Click" Content="&#xE8BB;"/>
</StackPanel>
</Grid>
</Border>
<!-- Content -->
<Grid Grid.Row="1" Margin="25">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<!-- Заголовок с иконкой --> <!-- Заголовок с иконкой -->
<StackPanel Orientation="Horizontal" Grid.Row="0" Margin="0,0,0,25"> <StackPanel Orientation="Horizontal" Grid.Row="0" Margin="0,0,0,25">
<TextBlock Text="⚠️" FontSize="36" Margin="0,0,15,0" VerticalAlignment="Center"/> <TextBlock Text="⚠️" FontSize="36" Margin="0,0,15,0" VerticalAlignment="Center"/>
@@ -74,5 +100,7 @@
Cursor="Hand" Cursor="Hand"
Click="ExitButton_Click"/> Click="ExitButton_Click"/>
</StackPanel> </StackPanel>
</Grid> </Grid>
</Grid>
</Border>
</Window> </Window>
+15
View File
@@ -1,5 +1,6 @@
using System; using System;
using System.Windows; using System.Windows;
using System.Windows.Input;
using QoSManager.Services; using QoSManager.Services;
namespace QoSManager.Views namespace QoSManager.Views
@@ -22,5 +23,19 @@ namespace QoSManager.Views
DialogResult = false; DialogResult = false;
Close(); Close();
} }
private void TitleBar_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
{
DragMove();
}
}
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
Close();
}
} }
} }