在Windows 10 32位安装上,C#应用程序会在随机且不频繁的时间点无提示地终止,这是一个严重的问题。例如,可能两次出现之间是一个月。有时只是一天。
基本系统规格:
Microsoft Windows 10 Enterprise 2016 LTSB
Version 10.0.14393 Build 14393
32-bit
使用https://docs.microsoft.com/zh-cn/windows-hardware/drivers/debugger/setting-and-clearing-flags-for-silent-process-exit,我们配置了静默进程出口监视。最后,我们有一些示例:
The process 'APPLICATIONPATH\APPLICATIONNAME.exe' was terminated by
the process 'C:\Windows\System32\svchost.exe' with termination code 1067.
The creation time for the exiting process was 0x01d43bd8689073eb.
查看为此设置的监视转储,我们获得了svchost的进程ID。该服务仍在系统上运行,并且显示以下服务列表:
这似乎是Windows的“ netsvcs”列表。从中打开转储svchost.exe
并查看此单个线程,并发现了一个有趣的调用栈:
ntdll.dll!_KiFastSystemCallRet@0 ()
ntdll.dll!_NtWaitForSingleObject@12 ()
ntdll.dll!RtlReportSilentProcessExit()
KERNELBASE.dll!TerminateProcess()
ubpm.dll!_UbpmpTerminateProcessCallback@12 ()
ubpm.dll!UbpmUtilsTimerCallback()
ntdll.dll!TppTimerpExecuteCallback()
ntdll.dll!TppWorkerThread()
kernel32.dll!@BaseThreadInitThunk@12 ()
ntdll.dll!__RtlUserThreadStart()
ntdll.dll!__RtlUserThreadStart@8 ()
UBPM是Unified Background Process Manager。但是,这如何终止我们的应用程序呢?又为什么呢?终止代码1067
告诉我们什么?
以下是“静默过程监控”中的日志条目:
Log Name: Application
Source: Microsoft-Windows-ProcessExitMonitor
Date: 2018-08-31 15:26:09
Event ID: 3001
Task Category: None
Level: Information
Keywords: Classic
User: SYSTEM
Computer: PC
Description:
The process 'APPLICATIONPATH\APPLICATIONNAME.exe' was terminated by the process 'C:\Windows\System32\svchost.exe' with termination code 1067. The creation time for the exiting process was 0x01d43ed2aee892ab.
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
<System>
<Provider Name="Microsoft-Windows-ProcessExitMonitor" Guid="{FD771D53-8492-4057-8E35-8C02813AF49B}" EventSourceName="Process Exit Monitor" />
<EventID Qualifiers="16384">3001</EventID>
<Version>0</Version>
<Level>4</Level>
<Task>0</Task>
<Opcode>0</Opcode>
<Keywords>0x80000000000000</Keywords>
<TimeCreated SystemTime="2018-08-31T13:26:09.988216500Z" />
<EventRecordID>4853</EventRecordID>
<Correlation />
<Execution ProcessID="0" ThreadID="0" />
<Channel>Application</Channel>
<Computer>PC</Computer>
<Security UserID="S-1-5-18" />
</System>
<EventData Name="EVENT_PROCESSTERMINATION_CROSSPROCESS">
<Data Name="param1">APPLICATIONPATH\APPLICATIONNAME.exe</Data>
<Data Name="param2">C:\Windows\System32\svchost.exe</Data>
<Data Name="param3">1067</Data>
<Data Name="param4">01d43ed2aee892ab</Data>
</EventData>
</Event>
注意:在应用终止时,PC尚未关闭,事件日志中也没有其他任何指示来说明终止过程的原因。
更新1:这里有一些额外的细节(试图回答评论中的所有问题):
更新2:我们使用nuget包TaskScheduler
通过代码来设置任务。请注意,我们没有设置ExecutionTimeLimit,因此应为Nothing并因此为无穷大。
using (TaskService m_service = new TaskService())
{
var task = m_service.NewTask();
task.Principal.UserId = userId;
task.Principal.LogonType = TaskLogonType.InteractiveToken;
task.Principal.RunLevel = TaskRunLevel.Highest;
task.Settings.Enabled = true;
task.Settings.MultipleInstances = TaskInstancesPolicy.IgnoreNew;
task.Settings.Hidden = false;
// NOTICE: A subset of the following 4 settings will cause app to hang on Win10
//task.Settings.AllowHardTerminate = true;
//task.Settings.DisallowStartOnRemoteAppSession = false;
//task.Settings.RunOnlyIfLoggedOn = true;
var trigger = (LogonTrigger)task.Triggers.Add(new LogonTrigger());
trigger.Enabled = true;
trigger.UserId = userId;
task.Actions.Add(new ExecAction(executableFilePath, arguments: null,
workingDirectory: m_installDirectoryPath));
if (!IsAdministrator())
{
var message = "Cannot register task with your current identity's permissions level.";
m_logger.Error(message);
}
m_service.RootFolder.RegisterTaskDefinition(taskName, task, TaskCreation.Create,
userId, password: null, logonType: TaskLogonType.InteractiveToken);
}
更新3:也许上面的声明是错误的,TaskScheduler
库中的默认值似乎是3天或72小时。
//
// Summary:
// Gets or sets the amount of time that is allowed to complete the task. By default,
// a task will be stopped 72 hours after it starts to run.
//
// Remarks:
// If a task is started on demand, the ExecutionTimeLimit setting is bypassed. Therefore,
// a task that is started on demand will not be terminated if it exceeds the ExecutionTimeLimit.
[DefaultValue(typeof(TimeSpan), "3")]
public TimeSpan ExecutionTimeLimit { get; set; }
更新4:唯一的事情是,在进程运行了超过3天(例如30天)之后,我们观察到静默进程退出,因此不确定这到底是什么。
更新5:不能正确观察到超过3天,因此,现在一切都清楚了,这是由于任务计划程序任务的设置不正确。错误的设置如下所示:
正确的设置是:
这只是一个理论,但是也许由于它是从计划任务开始的,所以任务计划程序在启动之后仍然以某种方式对流程具有“父”控制权?在我看来,Windows任务计划程序正在停止任务时,可能已经达到某些条件或出现了问题。也许您应该尝试使用start命令运行它,以便启动应用程序,但允许“计划任务”完成,因此可以从Windows Task Scheduler中释放对应用程序的控制。
EG C:\ Windows \ System32 \ cmd.exe / c开始“标题” C:\ Windows \ System32 \ notepad.exe
(或您正在运行的任何程序)
您必须运行cmd.exe,因为start命令是内置命令。另外,如果您阅读了start命令的文档,您会注意到title参数是必需的。您可以将其保留为“标题”,也可以将其设置为任何所需的名称。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句