Если вы работаете с Windows 10 IoT Enterprise и Shell Launcher для промышленных приложений, наверняка сталкивались с парадоксом: запускаете shutdown через виджет, а вместо перезагрузки система вдруг перезапускает оболочку или открывает неожиданный процесс. Это не баг, а особенность поведения Shell Launcher – но её можно обойти. Давайте разберёмся, как избежать конфликтов между командами завершения работы и реакциями на закрытие оболочки.
Почему Shell Launcher «мешает» shutdown?
Когда вы отправляете команду вроде
shutdown /r /t 0
Windows начинает завершать процессы – включая ваш кастомный shell (например, HMI-приложение). В этот момент Shell Launcher срабатывает по событию «оболочка закрыта» и выполняет реакцию, указанную в конфигурации. Если у вас выбрано «перезапустить shell», система попытается вернуться к исходному состоянию, отменяя запрос на перезагрузку.
Кстати, такая же проблема возникает при использовании logoff или даже при попытке завершить процесс через Task Manager. Всё потому, что Shell Launcher мониторит статус оболочки как отдельный триггер – он не «знает», что вы уже инициировали глобальное действие.
3 рабочих способа обойти конфликт
1. Проверьте стабильность основного приложения. В исходном кейсе проблема была в падении HMI-приложения перед вызовом shutdown. Если ваш скрипт или виджет запускает команду через утилиту (например, PowerShell), добавьте проверку на ошибки:
Start-Process "shutdown.exe" -ArgumentList "/r /t 1" -ErrorAction Stop
Использование -ErrorAction Stop гарантирует, что ошибка не будет проигнорирована.
2. Используйте скрипт-обёртку с управляемым выходом. Создайте BAT-файл или EXE, который:
- Принимает команду от интерфейса (например, через именованный канал или файл-флаг)
- Перед вызовом shutdown.exe меняет переменную окружения или записывает статус в реестр
- Возвращает специальный exit code, который Shell Launcher интерпретирует как «не реагировать»
Пример для BAT:
@echo off
REG ADD "HKCU\Software\ShutdownFlag" /v "InProgress" /d 1 /f
shutdown /r /t 3
exit 1234
В конфигурации Shell Launcher настройте реакцию для кода 1234 как «Do nothing»
3. Настройте Shell Launcher через XML-конфиг. Вместо стандартного интерфейса попробуйте явно указать условия:
<ShellLauncherConfiguration>
<DefaultAction Action="RestartShell"/>
<ExitCodes>
<ExitCode Value="1234" Action="DoNothing"/>
</ExitCodes>
</ShellLauncherConfiguration>
Так вы разделите сценарии: обычное закрытие оболочки → перезапуск, а ваш кастомный exit code → игнорирование.
Важно: не используйте реакцию «Do nothing» по умолчанию – это может заблокировать восстановление оболочки при случайных сбоях.
Частые ошибки и как их избежать
Слишком быстрое завершение. Если между закрытием оболочки и shutdown меньше секунды, Shell Launcher может «не успеть» получить ваш exit code. Добавьте задержку в 2-3 секунды в скрипте (но не через /t, а через ping -n).
Неправильные права. Скрипты, меняющие реестр или переменные, должны запускаться от имени администратора. Проверьте настройки через whoami /priv в консоли.
Кеширование конфигурации. После изменения XML-файла перезапустите службу Shell Launcher через PowerShell:
Restart-Service -Name "ShellLauncherSvc" -Force
Если после всех настроек команда всё равно «сбрасывается», проверьте журналы событий (Event Viewer → Windows Logs → System). Ищите события с источником ShellLauncher – там будет указано, какая реакция сработала и почему.
Кстати, не забывайте тестировать сценарии на реальном оборудовании: эмуляторы иногда пропускают тонкости работы с железом. И да, если используете обёрточные скрипты, добавляйте логирование – хотя бы запись в текстовый файл с timestamp. Это сэкономит часы отладки в будущем.