移除TopShelf

This commit is contained in:
xljiulang 2021-06-19 20:17:43 +08:00
parent 73bd06beed
commit 4c6eea1df4
5 changed files with 185 additions and 47 deletions

View File

@ -15,7 +15,8 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Topshelf" Version="4.3.0" /> <PackageReference Include="PInvoke.AdvApi32" Version="0.7.104" />
<PackageReference Include="Microsoft.Extensions.Hosting.WindowsServices" Version="5.0.1" />
<ProjectReference Include="..\FastGithub.Dns\FastGithub.Dns.csproj" /> <ProjectReference Include="..\FastGithub.Dns\FastGithub.Dns.csproj" />
</ItemGroup> </ItemGroup>
@ -23,6 +24,9 @@
<None Update="appsettings.json"> <None Update="appsettings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="README.MD">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -1,44 +0,0 @@
using Microsoft.Extensions.Hosting;
using System;
using System.Reflection;
using Topshelf;
namespace FastGithub
{
static class HostBuilderExtensions
{
/// <summary>
/// topShelf管理运行
/// </summary>
/// <param name="hostBuilder"></param>
/// <returns></returns>
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<AssemblyDescriptionAttribute>();
c.RunAsLocalSystem();
c.SetServiceName(assemblyName);
c.SetDisplayName(assemblyName);
c.SetDescription(assemblyDescription?.Description);
c.Service<IHost>(service => service
.ConstructUsing(() => hostBuilder.Build())
.WhenStarted(service => service.Start())
.WhenStopped(service => service.StopAsync().Wait())
);
});
}
else
{
hostBuilder.Build().Run();
}
}
}
}

View File

@ -10,7 +10,7 @@ namespace FastGithub
/// <param name="args"></param> /// <param name="args"></param>
public static void Main(string[] args) public static void Main(string[] args)
{ {
CreateHostBuilder(args).RunAsTopShelf(); CreateHostBuilder(args).Build().RunWithWindowsServiceControl();
} }
/// <summary> /// <summary>
@ -22,8 +22,10 @@ namespace FastGithub
{ {
return Host return Host
.CreateDefaultBuilder(args) .CreateDefaultBuilder(args)
.UseWindowsService()
.UseBinaryPathContentRoot()
.ConfigureServices((ctx, services) => .ConfigureServices((ctx, services) =>
{ {
services.AddGithubDns(ctx.Configuration); services.AddGithubDns(ctx.Configuration);
}); });
} }

11
FastGithub/README.MD Normal file
View File

@ -0,0 +1,11 @@
# FastGithub
github定制版的dns服务解析github最优的ip
### 使用说明
* 在局域网服务器或你的电脑运行FastGithub程序
* 手工修改你电脑的网络适配器的dns值为运行FastGithub的机器的ip
### windows服务
如果想在windows以服务方式运行以管理员身份运行cmd键入如下命令
* FastGithub.exe start // 安装并启动服务
* FastGithub.exe stop // 卸载并删除服务

View File

@ -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
{
/// <summary>
/// IHostBuilder扩展
/// </summary>
static class WindowServiceExtensions
{
/// <summary>
/// 控制命令
/// </summary>
private enum Command
{
Start,
Stop,
}
/// <summary>
/// 使用应用程序文件所在目录作为ContentRoot
/// </summary>
/// <param name="hostBuilder"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 以支持windows服务控制的方式运行
/// </summary>
/// <param name="host"></param>
public static void RunWithWindowsServiceControl(this IHost host)
{
var args = Environment.GetCommandLineArgs();
if (OperatingSystem.IsWindows() == false ||
Enum.TryParse<Command>(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<ILoggerFactory>();
if (loggerFactory != null)
{
var logger = loggerFactory.CreateLogger(nameof(WindowServiceExtensions));
logger.LogError(ex.Message);
}
else
{
Console.WriteLine(ex.Message);
}
}
}
/// <summary>
/// 安装并启动服务
/// </summary>
/// <param name="serviceName"></param>
/// <param name="binaryPath"></param>
/// <exception cref = "Win32Exception" ></ 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);
}
}
/// <summary>
/// 停止并删除服务
/// </summary>
/// <param name="serviceName"></param>
/// <exception cref = "Win32Exception" ></ 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();
}
}
}
}