我们的客户有一些运行由Task Scheduler激活的批处理作业的Windows 2003服务器。 执行该工作的实际程序是自定义的.exe进程,它们被汇总到.cmd脚本中,以便在计划的时间间隔到来时由Task Scheduler一起启动。 cmd脚本中的行可能会或可能不会使用Call命令来启动单独的.exe程序。
在此设置中,任务计划程序正在有效地监视cmd.exe,并且在使用Process Explorer时,可以观察到subprocess已停放在cmd.exe进程树下。 但是,当任务计划程序由于超出允许的时间限制而杀死cmd.exe时,subprocess可能不会与其父进程一起被终止并成为孤立进程。 这些进程无限期地停滞不前。 由于进程pipe理器中显示的进程线程的状态,我怀疑这些进程最终出现错误,并popup一个.NETdebugging器对话框(这些是.NET应用程序),因为批处理作业用户是一个单独的用户帐户。
最初,当我在Windows XP工作站上调查此行为时,发现从我的testing.cmd脚本启动的.exesubprocess会在Task Scheduler确定时间到了时与cmd.exe一起被终止。 我无法孤儿孩子的过程。
基于预感,我最终转移到Windows 2003机器来testing这个。 同样,subprocess终止像我的工作站。 然后,我的第二步是使用另一个用户帐户来运行计划的任务。 这一次,cmd.exe在超过时间限制后被杀死,但subprocess仍然保持不变,就像我的客户在其生产服务器中观察到的一样。
如果我抢先login该批处理用户帐户(这恰好是另一个pipe理员帐户)要求桌面会话,从我的testing.exe程序的任何错误或信息popup窗口将路由和呈现在该桌面上,让我看到实际的用户输出。 如果我只在计划的任务被调用后才login,桌面会话将不会“回收”现有进程的窗口; 他们永远保持隐藏。
我的问题是,我在这里丢失什么条件,可以导致任务计划程序不清除cmd.exe下的subprocess? 使用另一个会导致此行为的帐户有什么特别之处,但是在使用我当前的pipe理员帐户来运行预定任务时,请不要这么做?
Windows中的进程是独立的 – 杀死父进程不会自动终止subprocess。
尝试使用命令行上的“Taskkill / T”。 (/ T =“…终止指定的进程和由它启动的任何subprocess…”)
如果您有多个进程正在运行(我们经常有5个或更多“powershell.exe”正在运行),那么在“任务pipe理器”的“详细信息”选项卡中添加“命令行”列。 这应该清楚哪个进程ID是你想要closures的进程ID
如果您认为这是由于debugging器popup信息导致的,那么您是否尝试将代码封装在try{}catch{}块中并logging错误?
否则,也许你可以做的是让进程写入WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent())的输出WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent())
我怀疑孩子们不知道怎么升级到pipe理员,然后不能和父母一起被杀害。
要在不修改代码的情况下进行testing,可以编写另一个计划任务,试图使用taskkill杀死其他进程。 这个计划任务应该以pipe理员身份运行。 如果这样做,那么看起来这是一个安全问题。
如何使用SysInternals套件中的pskill实用程序。 这个程序可以通过名字来终止进程。 我会添加一个计划的任务,这将运行几分钟后,你期望的过程完成,将运行pskill终止它们。
PSKill也可以在您在命令行上提供的用户凭据下运行。
我不知道它会解决你的问题,但如果它与popup框相关(可能是 – 应用程序处于故障状态,暂停而不存在的用户决定如何处理) 。
看看http://blogs.msdn.com/shawnfa/archive/2004/07/15/184490.aspx ,看看你是否不能摆脱那些箱子…