feat(prepare-win): reboot to cmd shell before toolchain, only if needed
Up front, read Winlogon\Shell; if it isn't already cmd.exe, set it and do a clean reboot before running the toolchain — so the shell is genuinely cmd (not a killed-explorer half-state) for the whole servicing run. Idempotent: when the shell is already cmd (re-runs), skip the reboot. Replaces the earlier kill-explorer approach.
This commit is contained in:
@@ -668,18 +668,30 @@ def template_prepare_win(
|
||||
click.echo("[prepare-win] WinRM ready.")
|
||||
|
||||
try:
|
||||
# Switch the interactive shell to cmd.exe up front, before the toolchain
|
||||
# runs, so every reboot in the Windows Update 3010 loop already boots
|
||||
# without explorer — no shell crash-loop during heavy servicing. Drop the
|
||||
# live explorer now too (Winlogon relaunches the shell = cmd). Re-affirmed
|
||||
# before the final reboot and baked into post-install for redundancy.
|
||||
click.echo("[prepare-win] Setting interactive shell to cmd.exe ...")
|
||||
transport.run(
|
||||
"Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT"
|
||||
"\\CurrentVersion\\Winlogon' Shell 'cmd.exe' -Type String -Force\n"
|
||||
"Stop-Process -Name explorer -Force -ErrorAction SilentlyContinue\n",
|
||||
# Ensure the interactive shell is cmd.exe — via a clean reboot — before
|
||||
# the toolchain runs, so explorer never runs during the heavy servicing
|
||||
# (Windows Update 3010 loop) that would otherwise crash-loop it. Reboot
|
||||
# only when the shell wasn't already cmd, so re-runs don't reboot need-
|
||||
# lessly. Re-affirmed before the final reboot and baked into post-install.
|
||||
shell_res = transport.run(
|
||||
"(Get-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT"
|
||||
"\\CurrentVersion\\Winlogon').Shell",
|
||||
check=False,
|
||||
)
|
||||
if "cmd.exe" not in shell_res.stdout.strip().lower():
|
||||
click.echo(
|
||||
f"[prepare-win] Shell is '{shell_res.stdout.strip() or '?'}' — "
|
||||
"setting cmd.exe and rebooting ..."
|
||||
)
|
||||
transport.run(
|
||||
"Set-ItemProperty 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT"
|
||||
"\\CurrentVersion\\Winlogon' Shell 'cmd.exe' -Type String -Force",
|
||||
check=False,
|
||||
)
|
||||
_reboot_and_wait(transport, guest_ip, 5986, winrm_timeout)
|
||||
click.echo("[prepare-win] Shell is now cmd.exe.")
|
||||
else:
|
||||
click.echo("[prepare-win] Shell already cmd.exe — no reboot needed.")
|
||||
|
||||
# Ensure C:\CI exists
|
||||
transport.run(
|
||||
|
||||
@@ -434,6 +434,8 @@ def _make_transport() -> MagicMock:
|
||||
def _run(script: str = "", **kwargs: object) -> WinRmResult:
|
||||
if "PercentProcessorTime" in script: # pre-snapshot idle check
|
||||
return WinRmResult(stdout='{"cpu":2.0,"ram":21.0,"top":"idle"}', stderr="", returncode=0)
|
||||
if ").Shell" in script: # up-front shell check — already cmd, skip reboot
|
||||
return WinRmResult(stdout="cmd.exe", stderr="", returncode=0)
|
||||
if "ConvertTo-Json" in script:
|
||||
return WinRmResult(stdout=val_json, stderr="", returncode=0)
|
||||
return WinRmResult(stdout="CI_EXITCODE:0", stderr="", returncode=0)
|
||||
|
||||
Reference in New Issue
Block a user