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); + } + } + } + + /// + /// 安装并启动服务 + /// + /// + /// + /// + 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); + } + } + + /// + /// 停止并删除服务 + /// + /// + /// + 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(); + } + } + + } +}