diff --git a/MicrosocksGUI/App.axaml b/MicrosocksGUI/App.axaml
index de57a6d..0d3368d 100644
--- a/MicrosocksGUI/App.axaml
+++ b/MicrosocksGUI/App.axaml
@@ -1,5 +1,6 @@
@@ -11,5 +12,6 @@
+
\ No newline at end of file
diff --git a/MicrosocksGUI/MicrosocksGUI.csproj b/MicrosocksGUI/MicrosocksGUI.csproj
index d49259d..baaea60 100644
--- a/MicrosocksGUI/MicrosocksGUI.csproj
+++ b/MicrosocksGUI/MicrosocksGUI.csproj
@@ -22,6 +22,7 @@
None
All
+
all
diff --git a/MicrosocksGUI/Services/IServiceManager.cs b/MicrosocksGUI/Services/IServiceManager.cs
new file mode 100644
index 0000000..75004d5
--- /dev/null
+++ b/MicrosocksGUI/Services/IServiceManager.cs
@@ -0,0 +1,24 @@
+namespace MicrosocksGUI.Services;
+
+public interface IServiceManager
+{
+ public record Arguments(string Ip, string Port);
+
+ public void CreateIfNotExists();
+
+ public void Start();
+
+ public void Stop();
+
+ public void Restart();
+
+ public bool IsRunning();
+
+ public bool GetAutostart();
+
+ public void SetAutostart(bool autostart);
+
+ public Arguments GetArguments();
+
+ public void SetArguments(Arguments arguments);
+}
\ No newline at end of file
diff --git a/MicrosocksGUI/Services/WindowsServiceManager.cs b/MicrosocksGUI/Services/WindowsServiceManager.cs
new file mode 100644
index 0000000..18a6590
--- /dev/null
+++ b/MicrosocksGUI/Services/WindowsServiceManager.cs
@@ -0,0 +1,130 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Runtime.InteropServices;
+using System.ServiceProcess;
+
+namespace MicrosocksGUI.Services;
+
+public class WindowsServiceManager : IServiceManager
+{
+ private record NssmResult(string Output, string Errors);
+ private readonly ServiceController _serviceController = new("MicroSocks");
+
+ public void CreateIfNotExists()
+ {
+ if (!RunNssmProcess("status MicroSocks").Errors.Contains("Can't open service!"))
+ return;
+
+ var result = RunNssmProcess("install MicroSocks microsocks.exe -i 127.0.0.1 -p 1080");
+
+ if (!string.IsNullOrEmpty(result.Errors))
+ {
+ throw new ExternalException(result.Errors);
+ }
+ }
+
+ public void Start()
+ {
+ _serviceController.Refresh();
+
+ if (_serviceController.Status != ServiceControllerStatus.Stopped)
+ return;
+
+ _serviceController.Start();
+ _serviceController.WaitForStatus(ServiceControllerStatus.Running);
+ }
+
+ public void Stop()
+ {
+ _serviceController.Refresh();
+
+ if (_serviceController.Status != ServiceControllerStatus.Running)
+ return;
+
+ _serviceController.Stop();
+ _serviceController.WaitForStatus(ServiceControllerStatus.Stopped);
+ }
+
+ public void Restart()
+ {
+ Stop();
+ Start();
+ }
+
+ public bool IsRunning()
+ {
+ _serviceController.Refresh();
+ return _serviceController.Status == ServiceControllerStatus.Running;
+ }
+
+ public bool GetAutostart()
+ {
+ _serviceController.Refresh();
+ return _serviceController.StartType == ServiceStartMode.Automatic;
+ }
+
+ public void SetAutostart(bool autostart)
+ {
+ var param = autostart ? "SERVICE_AUTO_START" : "SERVICE_DEMAND_START";
+ var result = RunNssmProcess($"set MicroSocks Start {param}");
+
+ if (!string.IsNullOrEmpty(result.Errors))
+ {
+ throw new ExternalException(result.Errors);
+ }
+ }
+
+ public IServiceManager.Arguments GetArguments()
+ {
+ var result = RunNssmProcess("get MicroSocks AppParameters");
+
+ if (!string.IsNullOrEmpty(result.Errors))
+ {
+ throw new ExternalException(result.Errors);
+ }
+
+ return ParseArguments(result.Output);
+ }
+
+ public void SetArguments(IServiceManager.Arguments arguments)
+ {
+ var result = RunNssmProcess($"set MicroSocks AppParameters -i {arguments.Ip} -p {arguments.Port}");
+
+ if (!string.IsNullOrEmpty(result.Errors))
+ {
+ throw new ExternalException(result.Errors);
+ }
+ }
+
+ private IServiceManager.Arguments ParseArguments(string arguments)
+ {
+ var argumentsList = arguments.Split();
+ return new IServiceManager.Arguments(argumentsList[1], argumentsList[3]);
+ }
+
+ private NssmResult RunNssmProcess(string arguments)
+ {
+ using var process = new Process();
+
+ process.StartInfo = new ProcessStartInfo
+ {
+ FileName = ".\\nssm.exe",
+ Arguments = arguments,
+ UseShellExecute = false,
+ RedirectStandardOutput = true,
+ RedirectStandardError = true,
+ CreateNoWindow = true,
+ WorkingDirectory = Path.GetDirectoryName(".")
+ };
+
+ process.Start();
+
+ var output = process.StandardOutput.ReadToEnd().Replace("\0", "").Trim();
+ var errors = process.StandardError.ReadToEnd().Replace("\0", "").Trim();
+
+ process.WaitForExit();
+
+ return new NssmResult(output, errors);
+ }
+}
\ No newline at end of file
diff --git a/MicrosocksGUI/ViewModels/MainWindowViewModel.cs b/MicrosocksGUI/ViewModels/MainWindowViewModel.cs
index d9e8642..cd11a0e 100644
--- a/MicrosocksGUI/ViewModels/MainWindowViewModel.cs
+++ b/MicrosocksGUI/ViewModels/MainWindowViewModel.cs
@@ -1,155 +1,60 @@
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;
+using MicrosocksGUI.Services;
namespace MicrosocksGUI.ViewModels;
public partial class MainWindowViewModel : ViewModelBase
{
- private record Arguments(string Ip, string Port);
-
- [Reactive] private bool _isWorking;
- [Reactive] private bool _isAutoloading;
- [Reactive] private string? _ip;
- [Reactive] private string? _port;
+ [Reactive] private bool _isRunning;
+ [Reactive] private bool _isAutostart;
+ [Reactive] private string _ip = string.Empty;
+ [Reactive] private string _port = string.Empty;
+
+ private bool _isUpdateLocked;
private Timer _timer;
- //private readonly ManagementObject _serviceManager = new("Win32_Service.Name='Microsocks'");
- private readonly ServiceController _sc = new("MicroSocks");
+ private readonly IServiceManager _serviceManager = new WindowsServiceManager();
public MainWindowViewModel()
{
- // TODO Костыль, таймер запускается через секунду, а должен после инициализации ReactiveUI
+ _serviceManager.CreateIfNotExists();
_timer = new Timer(GetServiceStatus, null, TimeSpan.FromSeconds(1), TimeSpan.FromMilliseconds(100));
-
GetMicroSocksArguments();
}
+ private void GetServiceStatus(object? state)
+ {
+ if (_isUpdateLocked) return;
+
+ IsRunning = _serviceManager.IsRunning();
+ IsAutostart = _serviceManager.GetAutostart();
+ }
+
[ReactiveCommand]
private void SetServiceStatus()
{
- /*var serviceProps = _serviceManager.GetMethodParameters("Change");
- serviceProps["StartMode"] = IsAutoloading ? "Automatic" : "Manual";
- _serviceManager.InvokeMethod("Change", serviceProps, null);*/
-
- SetServiceAutoloading(IsAutoloading);
-
+ _isUpdateLocked = true;
- if (IsWorking)
+ _serviceManager.SetAutostart(IsAutostart);
+
+ if (IsRunning)
{
- StartService();
+ _serviceManager.Start();
}
else
{
- StopService();
+ _serviceManager.Stop();
}
-
-
-
- //_serviceManager.InvokeMethod(IsWorking ? "StartService" : "StopService", null, null);
- }
- private void StartService()
- {
- _sc.Refresh();
- if (_sc.Status != ServiceControllerStatus.Stopped) return;
-
- _sc.Start();
- _sc.WaitForStatus(ServiceControllerStatus.Running);
- //_serviceManager.InvokeMethod("StartService", null, null);
- }
-
- private void StopService()
- {
- _sc.Refresh();
- if (_sc.Status != ServiceControllerStatus.Running) return;
-
- _sc.Stop();
- _sc.WaitForStatus(ServiceControllerStatus.Stopped);
- //_serviceManager.InvokeMethod("StopService", null, null);
+ _isUpdateLocked = false;
}
- private void RestartService()
- {
- StopService();
- StartService();
- }
-
- private bool ServiceIsRunning()
- {
- _sc.Refresh();
- return _sc.Status == ServiceControllerStatus.Running;
- }
-
- private bool ServiceIsAutoloading()
- {
- _sc.Refresh();
- return _sc.StartType == ServiceStartMode.Automatic;
- }
-
- private void SetServiceAutoloading(bool isAutoloading)
- {
- using var process = new Process();
-
- var param = isAutoloading ? "SERVICE_AUTO_START" : "SERVICE_DEMAND_START";
- process.StartInfo = new ProcessStartInfo
- {
- FileName = ".\\nssm.exe",
- Arguments = $"set MicroSocks Start {param}",
- UseShellExecute = false,
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- CreateNoWindow = true,
- WorkingDirectory = Path.GetDirectoryName(".")
- };
- process.Start();
- process.WaitForExit();
- }
-
- private void GetServiceStatus(object? state)
- {
- //_sc.Refresh();
- //_serviceManager.Get();
- IsWorking = ServiceIsRunning();
- IsAutoloading = ServiceIsAutoloading();
-
- //IsWorking = _serviceManager["State"]?.ToString() == "Running";
- //IsAutoloading = _serviceManager["StartMode"]?.ToString() == "Auto";
- }
-
- Arguments ParseArguments(string arguments)
- {
- var argumentsList = arguments.Replace("\0", "").Trim().Split();
- return new Arguments(argumentsList[1], argumentsList[3]);
- }
-
[ReactiveCommand]
private void GetMicroSocksArguments()
{
- using var process = new Process();
- process.StartInfo = new ProcessStartInfo
- {
- FileName = ".\\nssm.exe",
- Arguments = "get MicroSocks AppParameters",
- UseShellExecute = false,
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- CreateNoWindow = true,
- WorkingDirectory = Path.GetDirectoryName(".")
- };
-
- process.Start();
- var output = process.StandardOutput.ReadToEnd();
- process.WaitForExit();
-
- var arguments = ParseArguments(output);
+ var arguments = _serviceManager.GetArguments();
Ip = arguments.Ip;
Port = arguments.Port;
}
@@ -157,20 +62,7 @@ public partial class MainWindowViewModel : ViewModelBase
[ReactiveCommand]
private void SetMicroSocksArguments()
{
- using var process = new Process();
- process.StartInfo = new ProcessStartInfo
- {
- FileName = ".\\nssm.exe",
- Arguments = $"set MicroSocks AppParameters -i {_ip} -p {_port}",
- UseShellExecute = false,
- RedirectStandardOutput = true,
- RedirectStandardError = true,
- CreateNoWindow = true,
- WorkingDirectory = Path.GetDirectoryName(".")
- };
- process.Start();
- process.WaitForExit();
-
- RestartService();
+ _serviceManager.SetArguments(new IServiceManager.Arguments(Ip, Port));
+ _serviceManager.Restart();
}
}
\ No newline at end of file
diff --git a/MicrosocksGUI/Views/MainWindow.axaml b/MicrosocksGUI/Views/MainWindow.axaml
index 1deef4a..81f5816 100644
--- a/MicrosocksGUI/Views/MainWindow.axaml
+++ b/MicrosocksGUI/Views/MainWindow.axaml
@@ -11,8 +11,7 @@
CanMaximize="False"
CanResize="False"
Width="250"
- Height="330"
- >
+ Height="330">