Skip to content

Commit

Permalink
winApi安装dnscrypt-proxy服务
Browse files Browse the repository at this point in the history
  • Loading branch information
xljiulang committed Nov 6, 2021
1 parent f997976 commit c11f7af
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 220 deletions.
59 changes: 29 additions & 30 deletions FastGithub.DomainResolve/DnscryptProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using static PInvoke.AdvApi32;

namespace FastGithub.DomainResolve
{
Expand All @@ -18,10 +19,11 @@ namespace FastGithub.DomainResolve
/// </summary>
sealed class DnscryptProxy
{
private const string PATH = "dnscrypt-proxy";
private const string NAME = "dnscrypt-proxy";

private readonly ILogger<DnscryptProxy> logger;
private readonly string processName;
private readonly string serviceName;
private readonly string exeFilePath;
private readonly string tomlFilePath;

/// <summary>
/// 相关进程
Expand All @@ -39,7 +41,14 @@ sealed class DnscryptProxy
/// <param name="logger"></param>
public DnscryptProxy(ILogger<DnscryptProxy> logger)
{
const string PATH = "dnscrypt-proxy";
const string NAME = "dnscrypt-proxy";

this.logger = logger;
this.processName = NAME;
this.serviceName = $"{nameof(FastGithub)}.{NAME}";
this.exeFilePath = Path.Combine(PATH, OperatingSystem.IsWindows() ? $"{NAME}.exe" : NAME);
this.tomlFilePath = Path.Combine(PATH, $"{NAME}.toml");
}

/// <summary>
Expand All @@ -55,7 +64,7 @@ public async Task StartAsync(CancellationToken cancellationToken)
}
catch (Exception ex)
{
this.logger.LogWarning($"{NAME}启动失败:{ex.Message}");
this.logger.LogWarning($"{this.processName}启动失败:{ex.Message}");
}
}

Expand All @@ -66,30 +75,22 @@ public async Task StartAsync(CancellationToken cancellationToken)
/// <returns></returns>
private async Task StartCoreAsync(CancellationToken cancellationToken)
{
var tomlPath = Path.Combine(PATH, $"{NAME}.toml");
var port = GetAvailablePort(IPAddress.Loopback.AddressFamily);
var localEndPoint = new IPEndPoint(IPAddress.Loopback, port);

await TomlUtil.SetListensAsync(tomlPath, localEndPoint, cancellationToken);
await TomlUtil.SetlogLevelAsync(tomlPath, 6, cancellationToken);
await TomlUtil.SetEdnsClientSubnetAsync(tomlPath, cancellationToken);

foreach (var process in Process.GetProcessesByName(NAME))
{
process.Kill();
process.WaitForExit();
}
await TomlUtil.SetListensAsync(this.tomlFilePath, localEndPoint, cancellationToken);
await TomlUtil.SetlogLevelAsync(this.tomlFilePath, 6, cancellationToken);
await TomlUtil.SetEdnsClientSubnetAsync(this.tomlFilePath, cancellationToken);

if (OperatingSystem.IsWindows() && Process.GetCurrentProcess().SessionId == 0)
{
StartDnscryptProxy("-service uninstall")?.WaitForExit();
StartDnscryptProxy("-service install")?.WaitForExit();
StartDnscryptProxy("-service start")?.WaitForExit();
this.process = Process.GetProcessesByName(NAME).FirstOrDefault(item => item.SessionId == 0);
ServiceInstallUtil.StopAndDeleteService(this.serviceName);
ServiceInstallUtil.InstallAndStartService(this.serviceName, this.exeFilePath, ServiceStartType.SERVICE_DEMAND_START);
this.process = Process.GetProcessesByName(this.processName).FirstOrDefault(item => item.SessionId == 0);
}
else
{
this.process = StartDnscryptProxy(string.Empty);
this.process = StartDnscryptProxy();
}

if (this.process != null)
Expand All @@ -109,17 +110,17 @@ public void Stop()
{
if (OperatingSystem.IsWindows() && Process.GetCurrentProcess().SessionId == 0)
{
StartDnscryptProxy("-service stop")?.WaitForExit();
StartDnscryptProxy("-service uninstall")?.WaitForExit();
ServiceInstallUtil.StopAndDeleteService(this.serviceName);
}

if (this.process != null && this.process.HasExited == false)
{
this.process.Kill();
}
}
catch (Exception ex)
{
this.logger.LogWarning($"{NAME}停止失败:{ex.Message }");
this.logger.LogWarning($"{this.processName}停止失败:{ex.Message }");
}
finally
{
Expand Down Expand Up @@ -160,16 +161,14 @@ private static int GetAvailablePort(AddressFamily addressFamily, int min = 5533)

/// <summary>
/// 启动DnscryptProxy进程
/// </summary>
/// <param name="arguments"></param>
private static Process? StartDnscryptProxy(string arguments)
/// </summary>
/// <returns></returns>
private Process? StartDnscryptProxy()
{
var fileName = OperatingSystem.IsWindows() ? $"{NAME}.exe" : NAME;
return Process.Start(new ProcessStartInfo
{
FileName = Path.Combine(PATH, fileName),
Arguments = arguments,
WorkingDirectory = PATH,
FileName = this.exeFilePath,
WorkingDirectory = Path.GetDirectoryName(this.exeFilePath),
UseShellExecute = false,
CreateNoWindow = true,
WindowStyle = ProcessWindowStyle.Hidden
Expand All @@ -182,7 +181,7 @@ private static int GetAvailablePort(AddressFamily addressFamily, int min = 5533)
/// <returns></returns>
public override string ToString()
{
return NAME;
return this.processName;
}
}
}
1 change: 1 addition & 0 deletions FastGithub.DomainResolve/FastGithub.DomainResolve.csproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<ItemGroup>
<PackageReference Include="PInvoke.AdvApi32" Version="0.7.104" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="5.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="5.0.0" />
<PackageReference Include="DNS" Version="6.1.0" />
Expand Down
88 changes: 88 additions & 0 deletions FastGithub.DomainResolve/ServiceInstallUtil.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
using System.IO;
using System.Runtime.Versioning;
using static PInvoke.AdvApi32;

namespace FastGithub.DomainResolve
{
public static class ServiceInstallUtil
{
/// <summary>
/// 安装并启动服务
/// </summary>
/// <param name="serviceName"></param>
/// <param name="binaryPath"></param>
/// <param name="startType"></param>
/// <returns></returns>
[SupportedOSPlatform("windows")]
public static bool InstallAndStartService(string serviceName, string binaryPath, ServiceStartType startType = ServiceStartType.SERVICE_AUTO_START)
{
using var hSCManager = OpenSCManager(null, null, ServiceManagerAccess.SC_MANAGER_ALL_ACCESS);
if (hSCManager.IsInvalid == true)
{
return false;
}

var hService = OpenService(hSCManager, serviceName, ServiceAccess.SERVICE_ALL_ACCESS);
if (hService.IsInvalid == true)
{
hService = CreateService(
hSCManager,
serviceName,
serviceName,
ServiceAccess.SERVICE_ALL_ACCESS,
ServiceType.SERVICE_WIN32_OWN_PROCESS,
startType,
ServiceErrorControl.SERVICE_ERROR_NORMAL,
Path.GetFullPath(binaryPath),
lpLoadOrderGroup: null,
lpdwTagId: 0,
lpDependencies: null,
lpServiceStartName: null,
lpPassword: null);
}

if (hService.IsInvalid == true)
{
return false;
}

using (hService)
{
return StartService(hService, 0, null);
}
}

/// <summary>
/// 停止并删除服务
/// </summary>
/// <param name="serviceName"></param>
/// <returns></returns>
[SupportedOSPlatform("windows")]
public static bool StopAndDeleteService(string serviceName)
{
using var hSCManager = OpenSCManager(null, null, ServiceManagerAccess.SC_MANAGER_ALL_ACCESS);
if (hSCManager.IsInvalid == true)
{
return false;
}

using var hService = OpenService(hSCManager, serviceName, ServiceAccess.SERVICE_ALL_ACCESS);
if (hService.IsInvalid == true)
{
return true;
}

var status = new SERVICE_STATUS();
if (QueryServiceStatus(hService, ref status) == true)
{
if (status.dwCurrentState != ServiceState.SERVICE_STOP_PENDING &&
status.dwCurrentState != ServiceState.SERVICE_STOPPED)
{
ControlService(hService, ServiceControl.SERVICE_CONTROL_STOP, ref status);
}
}

return DeleteService(hService);
}
}
}
6 changes: 3 additions & 3 deletions FastGithub.sln
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31808.319
# Visual Studio Version 16
VisualStudioVersion = 16.0.31320.298
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub", "FastGithub\FastGithub.csproj", "{C1099390-6103-4917-A740-A3002B542FE0}"
EndProject
Expand All @@ -15,7 +15,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.HttpServer", "Fa
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.PacketIntercept", "FastGithub.PacketIntercept\FastGithub.PacketIntercept.csproj", "{701FF90C-E651-4E0B-AE7F-84D1F17DD178}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FastGithub.UI", "FastGithub.UI\FastGithub.UI.csproj", "{5082061F-38D5-4F50-945E-791C85B9BDB5}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.UI", "FastGithub.UI\FastGithub.UI.csproj", "{5082061F-38D5-4F50-945E-791C85B9BDB5}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FastGithub.FlowAnalyze", "FastGithub.FlowAnalyze\FastGithub.FlowAnalyze.csproj", "{93478EAF-739C-47DA-B8FE-AEBA78A75E11}"
EndProject
Expand Down
3 changes: 1 addition & 2 deletions FastGithub/FastGithub.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="PInvoke.AdvApi32" Version="0.7.104" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.Network" Version="2.0.2.68" />
<ProjectReference Include="..\FastGithub.DomainResolve\FastGithub.DomainResolve.csproj" />
Expand All @@ -18,7 +17,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.1.2" />
<PackageReference Include="Serilog.Extensions.Hosting" Version="4.1.2" />
<PackageReference Include="Serilog.Sinks.Console" Version="4.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="3.2.0" />
Expand Down
Loading

0 comments on commit c11f7af

Please sign in to comment.