Windows 关闭时 Windows 服务引发错误
Posted
技术标签:
【中文标题】Windows 关闭时 Windows 服务引发错误【英文标题】:Windows Service Throws Error when Windows is Shutting Down 【发布时间】:2021-08-20 11:25:39 【问题描述】:我有一个使用 .NET 在 C# 中构建的 Windows 服务,每次用户注销、挂起、休眠、重置或关机时都会引发错误。在应用程序事件查看器中,它显示错误如下:-
Application: Service.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.ComponentModel.Win32Exception
Exception Info: System.InvalidOperationException
at System.ServiceProcess.ServiceController.GenerateNames()
at System.ServiceProcess.ServiceController.get_ServiceName()
at System.ServiceProcess.ServiceController.Stop()
at WellformationDesktopService.Wellformation+<OnSessionChange>d__3.MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_1(System.Object)
at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()
似乎失败的操作是使用 System.Net.HTTP.HttpClient 将提交发送到远程 API。该代码在 Windows 有效关闭用户空间时以外的任何其他时间都有效。
我需要做些什么来强制我的服务在无法执行该操作之前触发该操作?
提前致谢。
【问题讨论】:
听 ***.com/questions/5202119/… docs.microsoft.com/en-us/dotnet/api/… 并在你的循环中处理它们(使用取消令牌等)。虽然对于挂起,在 Windows 实际挂起之前您不太可能足够快地处理事件,所以也许只是捕获异常 在这种情况下,最好定期读取windows事件日志并转发该信息,虽然这意味着我们在接收信息方面会有点落后(可能直到关机才能收到第二天)至少我们会捕捉到所有合适的事件? 是的,这是可能的。请注意您的服务在收到 204(或您为成功提交设置的任何返回)之前关闭并认为它失败的竞争条件,因此您的远程服务必须有办法处理它。 【参考方案1】:您可以创建一个 .ps(powershell 脚本)来检查要停止的服务以及脚本强制运行您的 Windows 服务。
以下脚本将解决您的问题。
# start the following Windows services in the specified order:
[Array] $Services = 'Service1','Service2','Service3',...;
# loop through each service, if its running, start it
foreach($ServiceName in $Services)
$arrService = Get-Service -Name $ServiceName
write-host $ServiceName
while ($arrService.Status -eq 'Stopped')
Start-Service $ServiceName
write-host $arrService.status
write-host 'Service starting'
Start-Sleep -seconds 60
$arrService.Refresh()
if ($arrService.Status -eq 'Running')
Write-Host 'Service is now Running'
您可以随时通过Windows Task Scheduler 定期运行此脚本。
以及如何自动设置Windows服务启动类型。
Windows Service Start Automatically
【讨论】:
不幸的是,此应用程序需要在安全的用户环境中运行,我无法启动 PS 脚本,因为这需要提升权限,超出当前 Windows 服务所允许的权限。 @RichG windows服务管理等更多操作流程需要管理员权限。我不知道如何通过C#控制windows服务,但是你的系统管理员可以设置你的windows服务启动类型为 Automatically,它提供了当机器重新启动时您的 Windows 服务会自动运行。我在我的答案中添加了如何做的链接。【参考方案2】:我们已根据上述@Martheen 的建议纠正了该问题,现在一切正常。我们忽略 Windows 关闭事件,但在启动时查找用户的最后一次注销并使用该时间结束他们的会话,并在下次使用机器时提交。
谢谢
【讨论】:
以上是关于Windows 关闭时 Windows 服务引发错误的主要内容,如果未能解决你的问题,请参考以下文章
未关闭虚拟机直接关闭vmware引发的一系列问题——Windows下linux虚拟机