Pull to refresh

Консольные окна-«зомби», или как перезагрузить Windows без дурацких вопросов

Development for Windows *

Вчера я уже не первый раз столкнулся с забавной проблемой в Windows Server 2008 – после выхода из FAR Manager у меня осталось висеть консольное окно-«зомби».

Такое окно обладает поистине замечательным свойством – его нельзя закрыть. Кроме того, если у вас появилось такое окно, перезагрузить Windows у вас не получится – все ваши попытки будут заканчиваться появлением в Event Log сообщения The attempt by user ***\*** to restart/shutdown computer *** failed.

На фоне этого отсутствие соответствующего процесса в списке задач кажется такой мелочью… ;-)



Моя вчерашняя проблема усугублялась тем, что появилась как раз после деплоймента новой версии приложения, и для его успешного завершения мне обязательно нужно было перезагрузить сервер. Когда я сталкивался с проблемой окон-«зомби» ранее, я останавливал все сервисы и перезагружал сервер по питанию. Но вчера у меня такой возможности не было – сервер находился, мягко говоря, очень далеко, IP-KVM к нему подключен не был, и местный персонал, который мог бы применить к серверу крайние меры воздействия, также был недоступен.

Кстати, утилиты shutdown и psshutdown я попробовал в первые же минуты, никакого эффекта. Судя по всему, они используют все тот же вызов ExitWindowsEx(), который рассылает множество уведомлений, ожидает на них ответа и т.п.

В спешном порядке перекинув приложение на другой сервер, я стал искать, как же можно решить эту проблему?

Пообщавшись с друзьями, я выяснил, что я не единственный, кто сталкивался с этой проблемой, но решение они мне подсказать не смогли, т.к. так же, как и я, «решали» ее отключением питания сервера.

После того как я еще немного покопался в i-net, у меня появилось подозрение, кто виноват в моих мучениях – если верить VS Debugger Team, проблема вызвана ошибкой в csrss (Client/Server Runtime Subsystem), и появилась она больше года назад, после выхода обновления KB978037, и в этой же статье KB приведена ссылка на hotfix (KB982551). И несмотря на то, что в списке операционных систем, которые эта ошибка затрагивает, Windows Server 2008 отсутствует, симптомы очень похожие.

К сожалению, установка круга подозреваемых мало приблизила меня к решению проблемы, и я продолжил свои поиски. Очень быстро я нашел информацию, что в Windows 2000 была функция «Emergency Shutdown»:

HOW TO: Perform an Emergency Shutdown in Windows
http://support.microsoft.com/kb/279134/en-us


К сожалению, из-за изменившегося интерфейса мне не удалось выяснить, осталась ли такая функция в Windows Server 2008 (поиск по словам «emergency shutdown windows 2008» никаких результатов не принес), но вот дискуссия 10-ти летней давности на web-сайте CodeGuru, посвященная этой функции, натолкнула меня на мысль воспользоваться для перезагрузки вызовом NtShutdownSystem().

Проконсультировавшись на всякий случай с Марком Руссиновичем (в его печатной ипостаси ;-), я решил, что да, это то, что надо! И взяв за основу код, который Alex Fedotov (к сожалению, ссылка на его home page сейчас не работает… но, может быть, он прочитает этот пост, и я смогу выразить ему благодарность? :) привел в упомянутой выше дискуссии, я написал небольшую утилиту, слегка облагороженный вариант которой можно загрузить по ссылке в конце поста.

И эта утилита мне помогла! А если бы я еще умудрился проверить ее работу на специально запущенной для этого виртуалке, а не на своей рабочей станции, потеряв при этом кое-какие несохраненные данные, я бы был просто безумно счастлив! ;-)

Кстати, уже после того, как я решил проблему, на форуме TechNet мне предложили еще один вариант, а именно – выполнить утилиту shutdown от имени системного эккаунта, но работоспособность этого варианта я пока не проверил.

Загрузить утилиту Force Reboot (исходный код + бинарник)
Tags:
Hubs:
Total votes 75: ↑65 and ↓10 +55
Views 6.5K
Comments 82
Comments Comments 82

Posts