当前位置: 首页 > news >正文

怎么给网站添加图标山西手机版建站系统哪家好

怎么给网站添加图标,山西手机版建站系统哪家好,天眼查询企业信息电话,wordpress 教程 pdf上一篇文章我们了解了如何为 Worker Service 添加 Serilog 日志记录#xff0c;今天我接着介绍一下如何将 Worker Service 作为 Windows 服务运行。我曾经在前面一篇文章的总结中提到过可以使用 sc.exe 实用工具将 Worker Service 安装为 Windows 服务运行#xff0c;本文中我… 上一篇文章我们了解了如何为 Worker Service 添加 Serilog 日志记录今天我接着介绍一下如何将 Worker Service 作为 Windows 服务运行。我曾经在前面一篇文章的总结中提到过可以使用 sc.exe 实用工具将 Worker Service 安装为 Windows 服务运行本文中我就来具体阐述一下如何实现它。SC 是什么sc.exe 是包含于 Windows SDK 的可用于控制服务的命令行实用程序它的命令对应于服务控制管理器(SCM)[1] 提供的函数。服务控制管理器(SCM) 是 Windows NT 系列操作系统中的一个特殊进程它在操作系统启动时由 wininit 进程启动用于启动和停止 Windows 进程包括设备驱动程序和启动程序。SCM 的主要功能是在系统启动时启动所有必需的服务它类似于类 Unix 系统上的 init 进程或者现代 Linux 发行版上使用的较新的 systemd init 系统用于启动各种系统守护进程[2]。SCM 是一个远程过程调用(RPC)服务服务配置和服务控制程序可以借它来控制远程计算机上的服务。打开 Windows 命令提示符窗口输入并运行 sc 命令您便可以看到 sc.exe 实用工具的帮助信息 sc描述:SC 是用来与服务控制管理器和服务进行通信的命令行程序。 用法:sc server [command] [service name] option1 option2...server 选项的格式为 \\ServerName可通过键入以下命令获取有关命令的更多帮助: sc [command]命令:query-----------查询服务的状态或枚举服务类型的状态。queryex---------查询服务的扩展状态或枚举服务类型的状态。start-----------启动服务。pause-----------向服务发送 PAUSE 控制请求。interrogate-----向服务发送 INTERROGATE 控制请求。continue--------向服务发送 CONTINUE 控制请求。stop------------向服务发送 STOP 请求。config----------更改服务的配置(永久)。description-----更改服务的描述。failure---------更改失败时服务执行的操作。failureflag-----更改服务的失败操作标志。sidtype---------更改服务的服务 SID 类型。privs-----------更改服务的所需特权。managedaccount--更改服务以将服务帐户密码标记为由 LSA 管理。qc--------------查询服务的配置信息。qdescription----查询服务的描述。qfailure--------查询失败时服务执行的操作。qfailureflag----查询服务的失败操作标志。qsidtype--------查询服务的服务 SID 类型。qprivs----------查询服务的所需特权。qtriggerinfo----查询服务的触发器参数。qpreferrednode--查询服务的首选 NUMA 节点。qmanagedaccount-查询服务是否将帐户与 LSA 管理的密码结合使用。qprotection-----查询服务的进程保护级别。quserservice----查询用户服务模板的本地实例。delete ----------(从注册表中)删除服务。create----------创建服务(并将其添加到注册表中)。control---------向服务发送控制。sdshow----------显示服务的安全描述符。sdset-----------设置服务的安全描述符。showsid---------显示与任意名称对应的服务 SID 字符串。triggerinfo-----配置服务的触发器参数。preferrednode---设置服务的首选 NUMA 节点。GetDisplayName--获取服务的 DisplayName。GetKeyName------获取服务的 ServiceKeyName。EnumDepend------枚举服务依赖关系。 ... 您可以从帮助信息中看到 sc 实用工具支持的所有命令集及其介绍。我们在本文中要用到的命令有create----------创建服务(并将其添加到注册表中)description-----更改服务的描述。start-----------启动服务。stop------------向服务发送 STOP 请求。delete ----------(从注册表中)删除服务。创建项目并发布§下载 Worker Service 源码我将基于上一篇文章中的 Worker Service 源码[3]来修改如果您安装有 git可以用下面的命令获取它git clone gitgithub.com:ITTranslate/WorkerServiceWithSerilog.git 然后使用 Visual Studio Code 打开此项目运行一下以确保一切正常dotnet build dotnet run §添加 Windows Services 依赖为了作为 Windows 服务运行我们需要我们的 Worker 监听来自 ServiceBase 的启动和停止信号ServiceBase 是将 Windows 服务系统公开给 .NET 应用程序的 .NET 类型。为此我们需要添加 Microsoft.Extensions.Hosting.WindowsServices NuGet 包dotnet add package Microsoft.Extensions.Hosting.WindowsServices 然后修改 Program.cs 中的 CreateHostBuilder 方法添加 UseWindowsService 方法调用public static IHostBuilder CreateHostBuilder(string[] args) Host.CreateDefaultBuilder(args).UseWindowsService() // Sets the host lifetime to WindowsServiceLifetime....ConfigureServices((hostContext, services) {services.AddHostedServiceWorker();}).UseSerilog(); //将 Serilog 设置为日志提供程序 然后运行一下构建命令确保一切正常dotnet build 不出意外您会看到 已成功生成 的提示。§发布程序运行 dotnet publish 命令将应用程序及其依赖项发布到文件夹我的操作系统是 win10 x64 系统[4]。dotnet publish -c Release -r win-x64 -o c:\test\workerpub 命令运行完成后您会在 C:\test\workerpub 文件夹中看到可执行程序及其所有依赖项。创建并运行服务首先需要特别注意的是当我们使用 sc.exe 实用工具管理服务时必须以管理员身份运行 Windows 命令提示符否则会执行失败。§安装服务安装服务我们需要用到创建服务命令 —— sc create。以管理员身份打开 Windows 命令提示符窗口输入并运行 sc create 命令可以看到此命令的的帮助信息 sc create描述:在注册表和服务数据库中创建服务项。 用法:sc server create [service name] [binPath ] option1 option2...选项: 注意: 选项名称包括等号。等号和值之间需要一个空格。type own|share|interact|kernel|filesys|rec|userown|usershare(默认 own)start boot|system|auto|demand|disabled|delayed-auto(默认 demand)error normal|severe|critical|ignore(默认 normal)binPath .exe 文件的 BinaryPathNamegroup LoadOrderGrouptag yes|nodepend 依存关系(以 / (斜杠)分隔)obj AccountName|ObjectName(默认 LocalSystem)DisplayName 显示名称password 密码 命令 sc create 的参数说明[5]server指定服务所在的远程服务器的名称。名称必须使用通用命名约定(UNC)格式 (例如\myserver) 。若要在本地运行 SC.exe请不要使用此参数。service name指定 getkeyname 操作返回的服务名称。binPath指定服务二进制文件的路径。binPath 没有默认值必须提供此字符串。displayname 显示名称指定一个友好名称用于标识用户界面程序中的服务。start {boot|system|auto|demand|disabled|delayed-auto}指定服务的启动类型。选项包括boot - 指定由启动加载程序加载的设备驱动程序。system - 指定在内核初始化过程中启动的设备驱动程序。auto - 指定一项服务该服务在计算机每次重新启动时自动启动并运行即使没有人登录到计算机。demand - 指定必须手动启动的服务。如果未指定 start 则此值为默认值。disabled - 指定无法启动的服务。若要启动已禁用的服务请将启动类型更改为其他某个值。delayed-auto - 指定一项服务该服务将在启动其他自动服务之后的短时间自动启动。注意事项1、每个命令行选项 (参数) 必须包含等号作为选项名称的一部分。2、选项与其值之间必须有一个空格例如type own如果遗漏了空格操作将失败。了解了 sc create 命令的用法不难得出此处我们所需要的命令如下sc create MyService binPath C:\test\workerpub\MyService.exe start auto displayname 技术译站的测试服务 运行以上命令输出以下结果[SC] CreateService 成功 运行 services.msc 命令打开本地服务列表可以看到我们的服务已经安装好了服务名称显示为 技术译站的测试服务。它没有描述处于已停止状态。§设置服务的描述输入并运行 sc description 命令可以看到此命令的的帮助信息 sc description 描述:设置服务的描述字符串。 用法:sc server description [service name] [description] 运行以下命令给该服务添加描述信息sc description MyService 这是一个由 Worker Service 实现的测试服务。 输出结果[SC] ChangeServiceConfig2 成功 运行成功以后按 F5 刷新服务列表您将看到服务描述已经更新了。§启动服务输入并运行 sc start 命令可以看到此命令的的帮助信息 sc start描述:启动服务运行。 用法:sc server start [service name] arg1 arg2 ... 输入以下命令启动服务sc start MyService 输出结果[SC] StartService 失败 1053:服务没有及时响应启动或控制请求。 启动失败了为什么呢查看一下 Windows 事件查看器 -- 应用程序显示的错误原因大致如下The process was terminated due to an unhandled exception. Exception Info: System.IO.FileNotFoundException: The configuration file appsettings.json was not found and is not optional. The physical path is C:\WINDOWS\system32\appsettings.json. 回头看一下 Program.cs 文件在 Main 方法中我们为配置设置的基路径是 Directory.GetCurrentDirectory()。但是作为 Windows Service 运行时默认的当前工作目录是 C:\WINDOWS\system32所以导致了这样的错误。为了解决这一问题我们需要在设置配置的基路径前添加一行 Directory.SetCurrentDirectory(AppContext.BaseDirectory)代码如下// 作为 Windows Service 运行时默认的当前工作目录是 C:\WINDOWS\system32会导致找不到配置文件 // 所以需要添加下面一行指定当前工作目录为应用程序所在的实际目录。 Directory.SetCurrentDirectory(AppContext.BaseDirectory);var configuration new ConfigurationBuilder().SetBasePath(Directory.GetCurrentDirectory()).AddJsonFile(appsettings.json).AddJsonFile($appsettings.{Environment.GetEnvironmentVariable(DOTNET_ENVIRONMENT) ?? Production}.json, true).Build(); 作为 Windows Service 运行时默认情况下Directory.GetCurrentDirectory() 为 C:\WINDOWS\system32AppDomain.CurrentDomain.BaseDirectory 和 AppContext.BaseDirectory 为应用程序所在的实际目录。因为在有的依赖程序包中有用到 Directory.GetCurrentDirectory() 获取来程序所在目录所以这里必须使用 Directory.SetCurrentDirectory 设置当前工作目录。再次启动服务 sc start MyServiceSERVICE_NAME: MyServiceTYPE : 10 WIN32_OWN_PROCESSSTATE : 2 START_PENDING(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)WIN32_EXIT_CODE : 0 (0x0)SERVICE_EXIT_CODE : 0 (0x0)CHECKPOINT : 0x0WAIT_HINT : 0x7d0PID : 21736FLAGS : 这次服务启动成功了。§停止服务运行以下命令停止 MyService 服务。sc stop MyService 输出结果SERVICE_NAME: MyServiceTYPE : 10 WIN32_OWN_PROCESSSTATE : 3 STOP_PENDING(STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)WIN32_EXIT_CODE : 0 (0x0)SERVICE_EXIT_CODE : 0 (0x0)CHECKPOINT : 0x0WAIT_HINT : 0x0 §删除服务运行以下命令(从注册表中)删除 MyService 服务。sc delete MyService 输出结果[SC] DeleteService 成功 至此我们使用 sc 实用工具演示了服务的创建、更改描述、启动、停止和删除。当服务创建完成以后您也可以使用 Windows 服务管理器来维护服务的启动、停止等。Windows Service 优雅退出§问题我查看了一下 C:\test\workerpub\Logs 目录下的日志信息发现当停止服务的时候它并没有像我将 Worker Service 作为控制台应用运行时那样优雅退出等待关闭前必须完成的任务正常结束后再退出。也就是说我在.NET Worker Service 如何优雅退出[6]中使用的方法在将 Worker Service 作为 Windows 服务运行时失效了。这是什么原因呢该如何解决呢§查找原因我们来看一下 UseWindowsService 方法的源代码其中有这样一行// https://github.com/dotnet/runtime/blob/main/src/libraries/Microsoft.Extensions.Hosting.WindowsServices/src/WindowsServiceLifetimeHostBuilderExtensions.csservices.AddSingletonIHostLifetime, WindowsServiceLifetime(); 也就是说当 Worker Service 作为 Windows Service 运行时使用的宿主(Host)生命周期控制类不再是作为控制台应用运行时的 ConsoleLifetime而是 WindowsServiceLifetime它派生自 ServiceBase。让我们来看一下 WindowsServiceLifetime 的源代码您会发现 WindowsServiceLifetime 类的 OnStop 和 OnShutdown 方法中调用了 ApplicationLifetime.StopApplication()而它的基类 ServiceBase 中当服务停止时调用了 OnStop 和 OnShutdown 方法。也就是说在 Windows 服务停止的时候已经调用了 ApplicationLifetime.StopApplication()。这就是我们在 Worker 中手动调用 StopApplication 失效的原因。问题的原因找到了该怎么解决它呢§解决方法功夫不负有心人在认真查阅了 dotnet runtime[7] 中 BackgroundService 、WindowsServiceLifetime 和 ApplicationLifetime 类的源代码后终于找到了解决方法。既然 WindowsServiceLifetime 中调用了 StopApplication那我就换别的方法呗。注意到 ApplicationLifetime 的属性 ApplicationStopping类型为 CancellationToken它的注释是Triggered when the application host is performing a graceful shutdown. Request may still be in flight. Shutdown will block until this event completes.所以我们可以向它注册一个取消时调用的的委托操作。修改一下 Worker 类中的 StartAsync 方法添加以下代码// 注册应用停止前需要完成的操作 _hostApplicationLifetime.ApplicationStopping.Register(() {GetOffWork(); }); 向 ApplicationStopping 注册的委托在 StopAsync 之前运行。修改后 Worker 类的完整代码如下public class Worker : BackgroundService {/// summary/// 状态0-默认状态1-正在完成关闭前的必要工作2-正在执行 StopAsync/// /summaryprivate volatile int _status 0; //状态private readonly IHostApplicationLifetime _hostApplicationLifetime;private readonly ILoggerWorker _logger;public Worker(IHostApplicationLifetime hostApplicationLifetime, ILoggerWorker logger){_hostApplicationLifetime hostApplicationLifetime;_logger logger;}public override Task StartAsync(CancellationToken cancellationToken){// 注册应用停止前需要完成的操作_hostApplicationLifetime.ApplicationStopping.Register(() {GetOffWork();});_logger.LogInformation(上班了又是精神抖擞的一天output from StartAsync);return base.StartAsync(cancellationToken);}protected override async Task ExecuteAsync(CancellationToken stoppingToken){try{// 这里实现实际的业务逻辑while (!stoppingToken.IsCancellationRequested){try{_logger.LogInformation(Worker running at: {time}, DateTimeOffset.Now);await SomeMethodThatDoesTheWork(stoppingToken);}catch (Exception ex){_logger.LogError(ex, Global exception occurred. Will resume in a moment.);}await Task.Delay(TimeSpan.FromSeconds(5), stoppingToken);}}finally{_logger.LogWarning(My worker service shut down.);}}private async Task SomeMethodThatDoesTheWork(CancellationToken cancellationToken){string msg _status switch{1 正在完成关闭前的必要工作……,2 假装还在埋头苦干ing…… 其实我去洗杯子了,_ 我爱工作埋头苦干ing……};_logger.LogInformation(msg);await Task.CompletedTask;}/// summary/// 关闭前需要完成的工作/// /summaryprivate void GetOffWork(){_status 1;_logger.LogInformation(太好了下班时间到output from ApplicationStopping.Register Action at: {time}, DateTimeOffset.Now); _logger.LogDebug(开始处理关闭前必须完成的工作 at: {time}, DateTimeOffset.Now);_logger.LogInformation(糟糕有一个紧急 bug 需要下班前完成);_logger.LogInformation(啊啊啊我爱加班我要再干 20 秒Wait 1 );Task.Delay(TimeSpan.FromSeconds(20)).Wait();_logger.LogInformation(啊啊啊啊啊啊我爱加班我要再干 1 分钟Wait 2 );Task.Delay(TimeSpan.FromMinutes(1)).Wait();_logger.LogInformation(啊哈哈哈哈哈终于好了可以下班了);_logger.LogDebug(关闭前必须完成的工作处理完成 at: {time}, DateTimeOffset.Now);}public override Task StopAsync(CancellationToken cancellationToken){_status 2;_logger.LogInformation(准备下班了output from StopAsync at: {time}, DateTimeOffset.Now);_logger.LogInformation(去洗洗茶杯先……, DateTimeOffset.Now);Task.Delay(30_000).Wait();_logger.LogInformation(茶杯洗好了。, DateTimeOffset.Now);_logger.LogInformation(下班喽 ^_^, DateTimeOffset.Now);return base.StopAsync(cancellationToken);} } 代码修改完成以后停止服务重新发布程序。dotnet publish -c Release -r win-x64 -o c:\test\workerpub 再次启动服务然后关闭服务您会发现我们编写的 Windows Service 已经可以优雅退出了。这种方法不仅作为 Windows 服务运行时可以优雅退出而且作为控制台应用运行时也一样适用它比我在.NET Worker Service 如何优雅退出中介绍的方法更加完美。总结在本文中我通过一个实例详细介绍了如何将 .NET Worker Service 作为 Windows 服务运行并说明了如何使用 sc.exe 实用工具安装和管理服务。还改进了 Worker Service 优雅退出的方法使它不仅适用于控制台应用而且适用于 Windows 服务。当我们向 HostBuilder 添加了 .UseWindowsService() 方法调用后编译出的程序既可以作为控制台应用运行也可以作为 Windows 服务运行。您可以从 GitHub 下载本文中的源码[8]。相关阅读.NET Worker Service 入门介绍.NET Worker Service 如何优雅退出.NET Worker Service 添加 Serilog 日志记录相关链接https://docs.microsoft.com/zh-cn/windows/win32/services/service-control-manager ↩︎https://www.techopedia.com/definition/25522/service-control-manager-scm ↩︎https://github.com/ITTranslate/WorkerServiceWithSerilog ↩︎https://docs.microsoft.com/zh-cn/dotnet/core/tools/dotnet-publish ↩︎https://docs.microsoft.com/zh-cn/windows-server/administration/windows-commands/sc-create ↩︎https://mp.weixin.qq.com/s/voxAxh9rQQogE3_Yc1-eCQ ↩︎https://github.com/dotnet/runtime dotnet runtime ↩︎https://github.com/ITTranslate/WorkerServiceAsWindowsService 源码下载 ↩︎作者 技术译民出品 技术译站https://ITTranslator.cn/END
http://www.zqtcl.cn/news/464513/

相关文章:

  • frontpage网页制作视频教程昆明网站建设优化企业
  • 工信部 诚信网站备案公司网络营销方案
  • 网站开发采集工具如何做网站内链优化
  • 在线做英语题的网站揭阳建站服务
  • 网站非法篡改wordpress的知名网站
  • 保定网建站模板uv推广平台
  • 股权分配系统建设网站wordpress mip 模板
  • 网站及其建设的心得体会昆明云南微网站
  • 详情页在线设计网站推荐广州建设网站企业
  • 设计师网站建设哪家网络公司做网站
  • 宣城网站开发专业制注册资金写100万后悔
  • 专业的高密做网站的建公司网站要多久
  • 蚌埠做网站哪家好WordPress强制ssl
  • 1m宽带做网站平台建站
  • 学习做ppt 的网站班会活动设计方案模板
  • 廊坊住房和城乡建设厅网站门户网站开发招标
  • 免费下载网站设计方案wordpress zenmeyong
  • 网站建设与维护相关知识网站建设遵循的规范
  • 网站建设费科目东莞市塘厦镇
  • 网站建设策划书1万字深圳公司网站设计企业
  • 建设企业网站小微asp iis设置网站路径
  • 分类信息网站营销小程序appid是什么
  • 营销软文是什么意思网络seo培训
  • 效果好的手机网站建设成都网站制作报价
  • 江门网站建设推广平台注册公司费用要多少
  • 淄博哪家公司做网站最好新手做地方门户网站
  • 做一个交易平台网站的成本深圳南山做网站的公司
  • 网站建设的开发的主要方法aspcms分类信息网站
  • 中国免费图片素材网站烟台电商网站开发
  • 网站框架图浅谈网站的主色调设计