From 4c6eea1df407d416a043473ac69e61cece8eaa7e Mon Sep 17 00:00:00 2001
From: xljiulang <366193849@qq.com>
Date: Sat, 19 Jun 2021 20:17:43 +0800
Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E9=99=A4TopShelf?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
FastGithub/FastGithub.csproj | 6 +-
FastGithub/HostBuilderExtensions.cs | 44 -------
FastGithub/Program.cs | 6 +-
FastGithub/README.MD | 11 ++
FastGithub/WindowServiceExtensions.cs | 165 ++++++++++++++++++++++++++
5 files changed, 185 insertions(+), 47 deletions(-)
delete mode 100644 FastGithub/HostBuilderExtensions.cs
create mode 100644 FastGithub/README.MD
create mode 100644 FastGithub/WindowServiceExtensions.cs
diff --git a/FastGithub/FastGithub.csproj b/FastGithub/FastGithub.csproj
index b86aa63..958d741 100644
--- a/FastGithub/FastGithub.csproj
+++ b/FastGithub/FastGithub.csproj
@@ -15,7 +15,8 @@
-
+
+
@@ -23,6 +24,9 @@
PreserveNewest
+
+ PreserveNewest
+
diff --git a/FastGithub/HostBuilderExtensions.cs b/FastGithub/HostBuilderExtensions.cs
deleted file mode 100644
index 926bff0..0000000
--- a/FastGithub/HostBuilderExtensions.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-using Microsoft.Extensions.Hosting;
-using System;
-using System.Reflection;
-using Topshelf;
-
-namespace FastGithub
-{
- static class HostBuilderExtensions
- {
- ///
- /// topShelf管理运行
- ///
- ///
- ///
- public static void RunAsTopShelf(this IHostBuilder hostBuilder)
- {
- if (OperatingSystem.IsWindows())
- {
- HostFactory.Run(c =>
- {
- var assembly = typeof(HostBuilderExtensions).Assembly;
- var assemblyName = assembly.GetName().Name;
- var assemblyDescription = assembly.GetCustomAttribute();
-
- c.RunAsLocalSystem();
-
- c.SetServiceName(assemblyName);
- c.SetDisplayName(assemblyName);
- c.SetDescription(assemblyDescription?.Description);
-
- c.Service(service => service
- .ConstructUsing(() => hostBuilder.Build())
- .WhenStarted(service => service.Start())
- .WhenStopped(service => service.StopAsync().Wait())
- );
- });
- }
- else
- {
- hostBuilder.Build().Run();
- }
- }
- }
-}
diff --git a/FastGithub/Program.cs b/FastGithub/Program.cs
index a4fe162..697213c 100644
--- a/FastGithub/Program.cs
+++ b/FastGithub/Program.cs
@@ -10,7 +10,7 @@ namespace FastGithub
///
public static void Main(string[] args)
{
- CreateHostBuilder(args).RunAsTopShelf();
+ CreateHostBuilder(args).Build().RunWithWindowsServiceControl();
}
///
@@ -22,8 +22,10 @@ namespace FastGithub
{
return Host
.CreateDefaultBuilder(args)
+ .UseWindowsService()
+ .UseBinaryPathContentRoot()
.ConfigureServices((ctx, services) =>
- {
+ {
services.AddGithubDns(ctx.Configuration);
});
}
diff --git a/FastGithub/README.MD b/FastGithub/README.MD
new file mode 100644
index 0000000..215e549
--- /dev/null
+++ b/FastGithub/README.MD
@@ -0,0 +1,11 @@
+# FastGithub
+github定制版的dns服务,解析github最优的ip
+
+### 使用说明
+* 在局域网服务器或你的电脑运行FastGithub程序
+* 手工修改你电脑的网络适配器的dns,值为运行FastGithub的机器的ip
+
+### windows服务
+如果想在windows以服务方式运行,以管理员身份运行cmd,键入如下命令
+* FastGithub.exe start // 安装并启动服务
+* FastGithub.exe stop // 卸载并删除服务
diff --git a/FastGithub/WindowServiceExtensions.cs b/FastGithub/WindowServiceExtensions.cs
new file mode 100644
index 0000000..9de3750
--- /dev/null
+++ b/FastGithub/WindowServiceExtensions.cs
@@ -0,0 +1,165 @@
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+using PInvoke;
+using System;
+using System.IO;
+using System.Linq;
+using static PInvoke.AdvApi32;
+
+namespace FastGithub
+{
+ ///
+ /// IHostBuilder扩展
+ ///
+ static class WindowServiceExtensions
+ {
+ ///
+ /// 控制命令
+ ///
+ private enum Command
+ {
+ Start,
+ Stop,
+ }
+
+ ///
+ /// 使用应用程序文件所在目录作为ContentRoot
+ ///
+ ///
+ ///
+ public static IHostBuilder UseBinaryPathContentRoot(this IHostBuilder hostBuilder)
+ {
+ var contentRoot = Path.GetDirectoryName(Environment.GetCommandLineArgs().First());
+ if (contentRoot != null)
+ {
+ Environment.CurrentDirectory = contentRoot;
+ hostBuilder.UseContentRoot(contentRoot);
+ }
+ return hostBuilder;
+ }
+
+ ///
+ /// 以支持windows服务控制的方式运行
+ ///
+ ///
+ public static void RunWithWindowsServiceControl(this IHost host)
+ {
+ var args = Environment.GetCommandLineArgs();
+ if (OperatingSystem.IsWindows() == false ||
+ Enum.TryParse(args.Skip(1).FirstOrDefault(), true, out var cmd) == false)
+ {
+ host.Run();
+ return;
+ }
+
+ try
+ {
+ var binaryPath = args.First();
+ var serviceName = Path.GetFileNameWithoutExtension(binaryPath);
+
+ if (cmd == Command.Start)
+ {
+ InstallAndStartService(serviceName, binaryPath);
+ }
+ else if (cmd == Command.Stop)
+ {
+ StopAndDeleteService(serviceName);
+ }
+ }
+ catch (Exception ex)
+ {
+ var loggerFactory = host.Services.GetService();
+ if (loggerFactory != null)
+ {
+ var logger = loggerFactory.CreateLogger(nameof(WindowServiceExtensions));
+ logger.LogError(ex.Message);
+ }
+ else
+ {
+ Console.WriteLine(ex.Message);
+ }
+ }
+ }
+
+ ///
+ /// 安装并启动服务
+ ///
+ ///
+ ///
+ /// exception >
+ private static void InstallAndStartService(string serviceName, string binaryPath)
+ {
+ using var hSCManager = OpenSCManager(null, null, ServiceManagerAccess.SC_MANAGER_ALL_ACCESS);
+ if (hSCManager.IsInvalid == true)
+ {
+ throw new Win32Exception();
+ }
+
+ 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,
+ ServiceStartType.SERVICE_AUTO_START,
+ ServiceErrorControl.SERVICE_ERROR_NORMAL,
+ binaryPath,
+ lpLoadOrderGroup: null,
+ lpdwTagId: 0,
+ lpDependencies: null,
+ lpServiceStartName: null,
+ lpPassword: null);
+ }
+
+ if (hService.IsInvalid == true)
+ {
+ throw new Win32Exception();
+ }
+
+ using (hService)
+ {
+ StartService(hService, 0, null);
+ }
+ }
+
+ ///
+ /// 停止并删除服务
+ ///
+ ///
+ /// exception >
+ private static void StopAndDeleteService(string serviceName)
+ {
+ using var hSCManager = OpenSCManager(null, null, ServiceManagerAccess.SC_MANAGER_ALL_ACCESS);
+ if (hSCManager.IsInvalid == true)
+ {
+ throw new Win32Exception();
+ }
+
+ using var hService = OpenService(hSCManager, serviceName, ServiceAccess.SERVICE_ALL_ACCESS);
+ if (hService.IsInvalid == true)
+ {
+ return;
+ }
+
+ 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);
+ }
+ }
+
+ if (DeleteService(hService) == false)
+ {
+ throw new Win32Exception();
+ }
+ }
+
+ }
+}