公司网站建设推荐q479185700顶上,苏州网络营销推广软件运营,济宁创新网络运营有限公司,免费微信小程序模板实现一个监控 IP 的 windows 服务Intro我们公司的 VPN 用自己的电脑连公司的台式机的时候需要用 IP 地址#xff0c;有一次尝试去连的时候发现连不上#xff0c;第二天到公司发现 IP 变掉了#xff0c;不是之前连的 IP 了#xff0c;于是就想写一个简单 Windows 服务来监控…实现一个监控 IP 的 windows 服务Intro我们公司的 VPN 用自己的电脑连公司的台式机的时候需要用 IP 地址有一次尝试去连的时候发现连不上第二天到公司发现 IP 变掉了不是之前连的 IP 了于是就想写一个简单 Windows 服务来监控台式机的 IP 变化Overview在 C# 里我们可以使用 Dns.GetHostAddresses() 方法来获取 IP 地址我们可以每隔一段时间就判断一下当前的 IP 地址为了方便测试可以把这个时间定义在配置里这样本地开发的时候比较方便为了避免消息太多我们可以做一个简单的检查如果 IP 地址不变就不发消息了只有当 IP 信息变化的时候再发消息我们办公使用的是 Google Chat, 所以打算使用 Google Chat 来发消息也可以根据需要改成自己想用的通知方式Implement首先我们可以新建一个 worker 服务使用 dotnet cli 新建即可dotnet new worker -n IpMonitor如果不习惯没有解决方案文件也可以新建一个解决方案文件并将项目添加到解决方案文件中cd IpMonitor
dotnet new sln
dotnet sln add ./IpMonitor.csproj然后我们来改造我们的 Worker, Worker 其实就是一个后台服务我们的服务比较简单就直接在上面改了public sealed class Worker : BackgroundService
{private readonly TimeSpan _period;private readonly INotification _notification;private readonly ILoggerWorker _logger;private volatile string _previousIpInfo string.Empty;public Worker(IConfiguration configuration, INotification notification, ILoggerWorker logger){_notification notification;_logger logger;_period configuration.GetAppSettingTimeSpan(MonitorPeriod);if (_period TimeSpan.Zero){_period TimeSpan.FromMinutes(10);}}protected override async Task ExecuteAsync(CancellationToken stoppingToken){using var timer new PeriodicTimer(_period);while (await timer.WaitForNextTickAsync(stoppingToken)){try{var host Dns.GetHostName();var ips await Dns.GetHostAddressesAsync(host, stoppingToken);var ipInfo ${Environment.MachineName} - {host}\n {ips.Order(new IpAddressComparer()).Select(x x.MapToIPv4().ToString()).StringJoin(, )};if (_previousIpInfo ipInfo){_logger.LogDebug(IpInfo not changed);continue;}_logger.LogInformation(Ip info: {IpInfo}, ipInfo);await _notification.SendNotification(ipInfo);_previousIpInfo ipInfo;}catch (Exception e){_logger.LogError(e, GetIp exception);}}}
}这里我们使用了 .NET 6 引入的 PeriodicTimer 来实现定时任务自定义了一个 IpAddressComparer 来对 IP 地址做一个排序实现如下public sealed class IpAddressComparer: IComparerIPAddress
{public int Compare(IPAddress? x, IPAddress? y){if (ReferenceEquals(x, y)) return 0;if (ReferenceEquals(null, y)) return 1;if (ReferenceEquals(null, x)) return -1;var bytes1 x.MapToIPv4().ToString().SplitArraybyte(new []{ . });var bytes2 y.MapToIPv4().ToString().SplitArraybyte(new []{ . });for (var i 0; i bytes1.Length; i){if (bytes1[i] ! bytes2[i]){return bytes1[i].CompareTo(bytes2[i]);}}return 0;}
}通知使用了 Google Chat 的 webhook API可以自定义一个 Space添加一个 webhook 即可添加成功即可获取一个 webhook URL, 发送消息 API 可以参考文档https://developers.google.com/chat/api/guides/message-formats/basic实现如下public sealed class GoogleChatNotification: INotification
{private readonly HttpClient _httpClient;private readonly string _webhookUrl;public GoogleChatNotification(HttpClient httpClient, IConfiguration configuration){_httpClient httpClient;_webhookUrl Guard.NotNullOrEmpty(configuration.GetAppSetting(GChatWebHookUrl));}public async Taskbool SendNotification(string text){using var response await _httpClient.PostAsJsonAsync(_webhookUrl, new { text });return response.IsSuccessStatusCode;}
}在 Program 文件中注册我们新加的服务就可以了然后我们进行一些改造来发布和部署 Windows 服务可以按照文档的提示将项目发布为单文件部署我比较喜欢 powershell写了两个简单的 powershell script 来安装和卸载 Windows 服务首先我们可以在项目里添加 Microsoft.Extensions.Hosting.WindowsServices 的引用并添加一些发布属性PropertyGroupPublishSingleFile Condition$(Configuration) Releasetrue/PublishSingleFileRuntimeIdentifierwin-x64/RuntimeIdentifierPlatformTargetx64/PlatformTarget
/PropertyGroup在 Program 中注册 windows 服务相关配置using IpMonitor;Host.CreateDefaultBuilder(args).ConfigureServices(services {services.AddHostedServiceWorker();services.AddSingletonHttpClient();services.AddSingletonINotification, GoogleChatNotification();})
#if !DEBUG// https://learn.microsoft.com/en-us/dotnet/core/extensions/windows-service.UseWindowsService(options {options.ServiceName IpMonitor;})
#endif.Build().Run();安装服务 powershell 脚本$serviceName IpMonitor
Write-Output serviceName: $serviceNamedotnet publish -c Release -o out
$destDir Resolve-Path .\out
$ipMonitorPath $destDir\IpMonitor.exeWrite-Output Installing service... $ipMonitorPath $destDir
New-Service $serviceName -BinaryPathName $ipMonitorPath
Start-Service $serviceName
Write-Output Service $serviceName started卸载服务 powershell 脚本$serviceName IpMonitor
Stop-Service $serviceName
Write-Output Service $serviceName stopped
Remove-Service $serviceName
Write-Output Service $serviceName removed运行效果如下脚本运行需要以管理员权限运行我们可以使用 Get-Service IpMonitor 来查看服务状态install也可以在任务管理器和服务中查看最后再把我们的服务卸载掉uninstallMore发布为 Windows 服务时如果有问题可以通过 event log 来排查在 event log 里可以看到我们服务的日志Referenceshttps://learn.microsoft.com/en-us/dotnet/core/extensions/windows-servicehttps://github.com/WeihanLi/SamplesInPractice/tree/master/IpMonitorhttps://developers.google.com/chat/api/guides/message-formats/basic