Introduced service management changes.

This commit is contained in:
2025-11-04 14:15:47 +08:00
parent d880ebeedb
commit 3a5cccbf62
2 changed files with 243 additions and 4 deletions

View File

@@ -141,6 +141,39 @@
</Setter>
</Style>
<!-- 🔵 Small Rounded Button Style for Service Tab -->
<Style x:Key="SmallRoundedButtonStyle" TargetType="Button">
<Setter Property="Background" Value="{DynamicResource PrimaryBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource TextLightBrush}"/>
<Setter Property="BorderBrush" Value="Transparent"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Padding" Value="12,8"/>
<Setter Property="Margin" Value="4"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}"
CornerRadius="8"
Padding="{TemplateBinding Padding}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource HoverBrush}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" Value="#2E5FA8"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Background" Value="#808080"/>
<Setter Property="Foreground" Value="#C0C0C0"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="TextBox">
@@ -489,9 +522,23 @@
Foreground="{DynamicResource TextDarkBrush}"/>
</StackPanel>
<WrapPanel Margin="0,10,0,0">
<Button Content="Refresh Status" Click="RefreshServiceStatus_Click"
Style="{StaticResource SmallRoundedButtonStyle}"
Margin="0,10,0,0" Width="150" HorizontalAlignment="Left"/>
Width="150" HorizontalAlignment="Left"/>
<Button Content="Install Service" Click="InstallService_Click"
Style="{StaticResource SmallRoundedButtonStyle}"
Width="150" HorizontalAlignment="Left"/>
<Button Content="Uninstall Service" Click="UninstallService_Click"
Style="{StaticResource SmallRoundedButtonStyle}"
Width="150" HorizontalAlignment="Left"/>
<Button Content="Start Service" Click="StartService_Click"
Style="{StaticResource SmallRoundedButtonStyle}"
Width="150" HorizontalAlignment="Left"/>
<Button Content="Stop Service" Click="StopService_Click"
Style="{StaticResource SmallRoundedButtonStyle}"
Width="150" HorizontalAlignment="Left"/>
</WrapPanel>
</StackPanel>
</Border>

View File

@@ -1017,5 +1017,197 @@ private async void RefreshButton_Click(object sender, RoutedEventArgs e)
}
}
private void InstallService_Click(object sender, RoutedEventArgs e)
{
ServiceLogOutput.Text = "Installing PSG-Oversight service...\n\n";
try
{
// Get the path to OversightService.exe
var exePath = Path.Combine(
AppDomain.CurrentDomain.BaseDirectory,
"..", "..", "..", "..", "OversightService", "bin", "Debug", "net8.0", "OversightService.exe"
);
exePath = Path.GetFullPath(exePath);
if (!File.Exists(exePath))
{
ServiceLogOutput.Text += $"ERROR: OversightService.exe not found at:\n{exePath}\n\n";
ServiceLogOutput.Text += "Please build the OversightService project first.";
return;
}
// Create the service using sc.exe
var startInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = "sc.exe",
Arguments = $"create PSG-Oversight binPath=\"{exePath}\" start=auto DisplayName=\"PSG Oversight Service\"",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
Verb = "runas" // Request admin elevation
};
var process = System.Diagnostics.Process.Start(startInfo);
process.WaitForExit();
var output = process.StandardOutput.ReadToEnd();
var error = process.StandardError.ReadToEnd();
ServiceLogOutput.Text += output;
if (!string.IsNullOrEmpty(error))
{
ServiceLogOutput.Text += $"ERROR: {error}\n";
}
if (process.ExitCode == 0)
{
ServiceLogOutput.Text += "\n✅ Service installed successfully!\n";
RefreshServiceStatus_Click(sender, e);
}
else
{
ServiceLogOutput.Text += $"\n❌ Service installation failed with exit code: {process.ExitCode}\n";
}
}
catch (Exception ex)
{
ServiceLogOutput.Text += $"ERROR: {ex.Message}\n";
ServiceLogOutput.Text += "\nNote: This operation requires administrator privileges.\n";
}
}
private void UninstallService_Click(object sender, RoutedEventArgs e)
{
ServiceLogOutput.Text = "Uninstalling PSG-Oversight service...\n\n";
try
{
// Stop the service first if it's running
try
{
var service = System.ServiceProcess.ServiceController.GetServices()
.FirstOrDefault(s => s.ServiceName == "PSG-Oversight");
if (service != null && service.Status == System.ServiceProcess.ServiceControllerStatus.Running)
{
ServiceLogOutput.Text += "Stopping service first...\n";
service.Stop();
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(30));
ServiceLogOutput.Text += "Service stopped.\n\n";
}
}
catch { }
// Delete the service using sc.exe
var startInfo = new System.Diagnostics.ProcessStartInfo
{
FileName = "sc.exe",
Arguments = "delete PSG-Oversight",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
Verb = "runas" // Request admin elevation
};
var process = System.Diagnostics.Process.Start(startInfo);
process.WaitForExit();
var output = process.StandardOutput.ReadToEnd();
var error = process.StandardError.ReadToEnd();
ServiceLogOutput.Text += output;
if (!string.IsNullOrEmpty(error))
{
ServiceLogOutput.Text += $"ERROR: {error}\n";
}
if (process.ExitCode == 0)
{
ServiceLogOutput.Text += "\n✅ Service uninstalled successfully!\n";
RefreshServiceStatus_Click(sender, e);
}
else
{
ServiceLogOutput.Text += $"\n❌ Service uninstallation failed with exit code: {process.ExitCode}\n";
}
}
catch (Exception ex)
{
ServiceLogOutput.Text += $"ERROR: {ex.Message}\n";
ServiceLogOutput.Text += "\nNote: This operation requires administrator privileges.\n";
}
}
private void StartService_Click(object sender, RoutedEventArgs e)
{
ServiceLogOutput.Text = "Starting PSG-Oversight service...\n\n";
try
{
var service = System.ServiceProcess.ServiceController.GetServices()
.FirstOrDefault(s => s.ServiceName == "PSG-Oversight");
if (service == null)
{
ServiceLogOutput.Text += "ERROR: Service is not installed.\n";
return;
}
if (service.Status == System.ServiceProcess.ServiceControllerStatus.Running)
{
ServiceLogOutput.Text += "Service is already running.\n";
return;
}
service.Start();
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Running, TimeSpan.FromSeconds(30));
ServiceLogOutput.Text += "✅ Service started successfully!\n";
RefreshServiceStatus_Click(sender, e);
}
catch (Exception ex)
{
ServiceLogOutput.Text += $"ERROR: {ex.Message}\n";
ServiceLogOutput.Text += "\nNote: This operation may require administrator privileges.\n";
}
}
private void StopService_Click(object sender, RoutedEventArgs e)
{
ServiceLogOutput.Text = "Stopping PSG-Oversight service...\n\n";
try
{
var service = System.ServiceProcess.ServiceController.GetServices()
.FirstOrDefault(s => s.ServiceName == "PSG-Oversight");
if (service == null)
{
ServiceLogOutput.Text += "ERROR: Service is not installed.\n";
return;
}
if (service.Status == System.ServiceProcess.ServiceControllerStatus.Stopped)
{
ServiceLogOutput.Text += "Service is already stopped.\n";
return;
}
service.Stop();
service.WaitForStatus(System.ServiceProcess.ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(30));
ServiceLogOutput.Text += "✅ Service stopped successfully!\n";
RefreshServiceStatus_Click(sender, e);
}
catch (Exception ex)
{
ServiceLogOutput.Text += $"ERROR: {ex.Message}\n";
ServiceLogOutput.Text += "\nNote: This operation may require administrator privileges.\n";
}
}
}
}