WMI for managment, nssm for editing paramns of service

This commit is contained in:
2025-11-22 13:17:25 +03:00
parent ca6dd7be8f
commit 3bfef4ba03
4 changed files with 55 additions and 83 deletions

View File

@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<TargetFramework>net9.0-windows</TargetFramework>
<Nullable>enable</Nullable>
<ApplicationManifest>app.manifest</ApplicationManifest>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
@ -27,5 +27,7 @@
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="System.Management" Version="10.0.0" />
<PackageReference Include="System.ServiceProcess.ServiceController" Version="10.0.0" />
</ItemGroup>
</Project>

View File

@ -1,10 +1,13 @@
using System;
using System.Diagnostics;
using System.IO;
using System.Management;
using System.Runtime.Versioning;
using System.Threading;
using System.Threading.Tasks;
using ReactiveUI;
using ReactiveUI.SourceGenerators;
using System.ServiceProcess;
namespace MicrosocksGUI.ViewModels;
@ -16,48 +19,39 @@ public partial class MainWindowViewModel : ViewModelBase
[Reactive] private string? _port;
private Timer _timer;
private ProcessStartInfo _getStatusProcessInfo = new()
{
FileName = ".\\nssm.exe",
Arguments = "status Microsocks",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
WorkingDirectory = Path.GetDirectoryName(".")
};
private ProcessStartInfo _getStartTypeProcessInfo = new()
{
FileName = ".\\nssm.exe",
Arguments = "get Microsocks Start",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
WorkingDirectory = Path.GetDirectoryName(".")
};
private readonly ManagementObject _serviceManager = new("Win32_Service.Name='Microsocks'");
public MainWindowViewModel()
{
// TODO Костыль, таймер запускается через секунду, а должен после инициализации ReactiveUI
_timer = new Timer(GetWorkingStatusFromService, null, TimeSpan.FromSeconds(1), TimeSpan.FromMilliseconds(100));
_timer = new Timer(GetServiceStatus, null, TimeSpan.FromSeconds(1), TimeSpan.FromMilliseconds(100));
GetMicroSocksArguments();
}
[ReactiveCommand]
private async Task SetWorkingStatusToService()
private void SetServiceStatus()
{
var serviceProps = _serviceManager.GetMethodParameters("Change");
serviceProps["StartMode"] = IsAutoloading ? "Automatic" : "Manual";
_serviceManager.InvokeMethod("Change", serviceProps, null);
_serviceManager.InvokeMethod(IsWorking ? "StartService" : "StopService", null, null);
}
var args = _isWorking ? "start Microsocks" : "stop Microsocks";
private void GetServiceStatus(object? state)
{
_serviceManager.Get();
IsWorking = _serviceManager["State"]?.ToString() == "Running";
IsAutoloading = _serviceManager["StartMode"]?.ToString() == "Auto";
}
ProcessStartInfo processInfo = new()
private void GetMicroSocksArguments()
{
using var process = new Process();
process.StartInfo = new ProcessStartInfo
{
FileName = ".\\nssm.exe",
Arguments = args,
Arguments = "get MicroSocks AppParameters",
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
@ -65,56 +59,20 @@ public partial class MainWindowViewModel : ViewModelBase
WorkingDirectory = Path.GetDirectoryName(".")
};
using var process = new Process();
process.StartInfo = processInfo;
process.Start();
}
private async void GetWorkingStatusFromService(object? state)
{
using (Process process = new Process())
{
process.StartInfo = _getStatusProcessInfo;
process.Start();
var output = process.StandardOutput.ReadToEnd();
var error = process.StandardError.ReadToEnd();
var output = await process.StandardOutput.ReadToEndAsync();
var error = await process.StandardError.ReadToEndAsync();
await process.WaitForExitAsync();
if (!string.IsNullOrEmpty(error))
{
//Console.WriteLine(error);
}
//Console.WriteLine(output.Replace("\0", "").Trim());
if (output.Replace("\0", "").Trim() == "SERVICE_RUNNING")
{
//Console.WriteLine("yes");
//IsWorking = true;
}
IsWorking = output.Replace("\0", "").Trim() == "SERVICE_RUNNING";
}
using (Process process = new Process())
{
process.StartInfo = _getStartTypeProcessInfo;
process.Start();
var output = await process.StandardOutput.ReadToEndAsync();
var error = await process.StandardError.ReadToEndAsync();
await process.WaitForExitAsync();
process.WaitForExit();
if (!string.IsNullOrEmpty(error))
{
Console.WriteLine(error);
}
IsAutoloading = output.Replace("\0", "").Trim() == "SERVICE_AUTO_START";
}
Console.WriteLine(output.Replace("\0", "").Trim());
//IsAutoloading = output.Replace("\0", "").Trim() == "SERVICE_AUTO_START";
}
}

View File

@ -29,7 +29,7 @@
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
IsChecked="{Binding IsWorking}"
Command="{Binding SetWorkingStatusToServiceCommand}">
Command="{Binding SetServiceStatusCommand}">
Работа
</ToggleButton>
@ -37,7 +37,8 @@
Grid.Column="1"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
IsChecked="{Binding IsAutoloading}">
IsChecked="{Binding IsAutoloading}"
Command="{Binding SetServiceStatusCommand}">
Автозапуск
</ToggleButton>
</Grid>

View File

@ -15,4 +15,15 @@
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
</application>
</compatibility>
<!--<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
&lt;!&ndash; UAC Запрос прав администратора &ndash;&gt;
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>-->
</assembly>