У нашего клиента есть серверы Windows 2003, на которых выполняются пакетные задания, активируемые планировщиком задач. Фактические программы, выполняющие эту работу, являются пользовательскими процессами .exe, и они объединены в сценарии .cmd, чтобы планировщик задач запускал их вместе, когда наступает запланированный интервал. Строки в сценариях cmd могут использовать или не использовать команду Call для запуска отдельных программ .exe.

В этой настройке планировщик задач эффективно отслеживает cmd.exe, а при использовании Process Explorer можно заметить, что дочерние процессы .exe припаркованы под деревом процессов cmd.exe. Однако, когда планировщик задач убивает cmd.exe из-за превышения допустимого ограничения по времени, дочерние процессы .exe не могут быть убиты вместе со своими родительскими и стать осиротевшими. Эти процессы остаются в тупике на неопределенный срок. Из-за состояния потоков процессов, показанных в Process Explorer, я подозреваю, что эти процессы заканчиваются ошибкой и выскакивают диалоговое окно отладчика .NET (это приложения .NET), которое нельзя увидеть, поскольку пользователь пакетного задания является отдельным пользователем учетная запись.

Первоначально, когда я исследовал это поведение на своей рабочей станции Windows XP, я заметил, что дочерние процессы .exe, запускаемые из моего тестового .cmd-скрипта, убиваются вместе с cmd.exe, когда планировщик задач решает, что время истекло. Я не мог осиротить дочерние процессы.

Основываясь на догадках, я в конце концов перешел на машину с Windows 2003, чтобы проверить это. Точно так же дочерние процессы должны быть завершены, как и на моей рабочей станции. Моим вторым шагом было использование другой учетной записи пользователя для выполнения запланированной задачи. На этот раз cmd.exe завершается после того, как лимит времени превышен, но дочерние процессы остаются в рабочем состоянии, как и то, что мой клиент наблюдал на своих производственных серверах.

Если я с упреждением войду в эту учетную запись пакетного пользователя (которая, как оказалось, была другой учетной записью администратора), чтобы заявить о сеансе рабочего стола, любые всплывающие окна с ошибками или информацией из моих тестовых программ .exe будут перенаправлены и отображены на этом рабочем столе, что позволит мне увидеть фактический вывод пользователя. Если я вхожу в систему только после того, как запланированная задача была вызвана, сеанс рабочего стола не будет «возвращать» окна существующих процессов; они остаются скрытыми навсегда.

Мой вопрос в том, какие условия мне здесь не хватает, из-за которых планировщик задач не уничтожает дочерние процессы в cmd.exe? Что особенного в использовании другой учетной записи, которая может вызвать такое поведение, но не при использовании моей текущей учетной записи администратора для запуска запланированной задачи?

answer

Попробуйте использовать "Taskkill / T" в командной строке. (/ T = «… Завершает указанный процесс и все дочерние процессы, которые были им запущены…»)

Если у вас запущено несколько процессов (у нас часто работает 5 или более «powershell.exe»), добавьте столбец «Командная строка» на вкладку «Подробности» в диспетчере задач. Это должно прояснить, какой идентификатор процесса вы хотите убить.

Процессы независимы в Windows - убийство родительского процесса не приводит к автоматическому завершению дочернего процесса.

Если вы думаете, что это связано с появлением сообщения отладчика, пробовали ли вы заключить код в try{}catch{}блок и зарегистрировать ошибку?

В противном случае, возможно, вы могли бы заставить процессы записывать вывод WindowsPrincipal wp = new WindowsPrincipal(WindowsIdentity.GetCurrent())

Я подозреваю, что дети каким-то образом повышают свой уровень привилегии до Администратора, а затем не могут быть убиты вместе с родителем.

Чтобы проверить это без изменения кода, вы можете написать еще одну запланированную задачу, которая пытается убить другие процессы с помощью taskkill . Это запланированное задание следует запускать от имени администратора. Если это сработает, значит, это проблема безопасности.

Как насчет использования утилиты pskill , которая является частью пакета SysInternals. Эта программа может уничтожать процессы по имени. Я бы добавил запланированную задачу, которая будет запускаться через несколько минут после того, как вы ожидаете завершения процессов, которая запустит pskill для их завершения.

PSKill также может работать под учетными данными пользователя, которые вы вводите в командной строке.

Я не знаю, что это решит вашу проблему, но если это связано со всплывающими окнами (а это может быть - приложение находится в неисправном состоянии и приостановлено, пока несуществующий пользователь решает, что с этим делать) .

Взгляните на http://blogs.msdn.com/shawnfa/archive/2004/07/15/184490.aspx и посмотрите, не сможете ли вы избавиться от этих ящиков ...