日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

实现一个监控 IP 的 windows 服务

發布時間:2023/12/14 windows 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 实现一个监控 IP 的 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?ILogger<Worker>?_logger;private?volatile?string?_previousIpInfo?=?string.Empty;public?Worker(IConfiguration?configuration,?INotification?notification,?ILogger<Worker>?logger){_notification?=?notification;_logger?=?logger;_period?=?configuration.GetAppSetting<TimeSpan>("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:?IComparer<IPAddress> {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().SplitArray<byte>(new?[]{?'.'?});var?bytes2?=?y.MapToIPv4().ToString().SplitArray<byte>(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?Task<bool>?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 的引用,并添加一些發布屬性

<PropertyGroup><PublishSingleFile?Condition="'$(Configuration)'?==?'Release'">true</PublishSingleFile><RuntimeIdentifier>win-x64</RuntimeIdentifier><PlatformTarget>x64</PlatformTarget> </PropertyGroup>

在 Program 中注冊 windows 服務相關配置

using?IpMonitor;Host.CreateDefaultBuilder(args).ConfigureServices(services?=>{services.AddHostedService<Worker>();services.AddSingleton<HttpClient>();services.AddSingleton<INotification,?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:?$serviceName"dotnet?publish?-c?Release?-o?out $destDir?=?Resolve-Path?".\out" $ipMonitorPath?=?"$destDir\IpMonitor.exe"Write-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

也可以在任務管理器和服務中查看

最后再把我們的服務卸載掉

uninstall

More

發布為 Windows 服務時如果有問題可以通過 event log 來排查,在 event log 里可以看到我們服務的日志

技術群:添加小編微信并備注進群

小編微信:mm1552923 ??

公眾號:dotNet編程大全? ??

References

  • https://learn.microsoft.com/en-us/dotnet/core/extensions/windows-service

  • https://github.com/WeihanLi/SamplesInPractice/tree/master/IpMonitor

  • https://developers.google.com/chat/api/guides/message-formats/basic

總結

以上是生活随笔為你收集整理的实现一个监控 IP 的 windows 服务的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。