From 9acd141cabbad6e9bf571f23c65acc52cc1d51ff Mon Sep 17 00:00:00 2001 From: yuanyuanxiang <962914132@qq.com> Date: Sun, 10 May 2026 17:36:46 +0200 Subject: [PATCH] Fix: Modern Terminal blank under SYSTEM; precise reason in info list --- build.ps1 | 12 ++++++++++ server/2015Remote/2015RemoteDlg.cpp | 19 ++++++++++++---- server/2015Remote/TerminalModuleLoader.h | 29 ++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/build.ps1 b/build.ps1 index f8bd28e..711768c 100644 --- a/build.ps1 +++ b/build.ps1 @@ -43,6 +43,18 @@ foreach ($pattern in $msBuildPaths) { } } +# 兜底:默认路径找不到(例如 VS 装在 D 盘)时,用 vswhere 反查。 +# vswhere.exe 由 VS Installer 维护,固定在 %ProgramFiles(x86)% 下,与 VS 本体盘符无关。 +if (-not $msBuild) { + $vswhere = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" + if (Test-Path $vswhere) { + $found = & $vswhere -latest -products * -requires Microsoft.Component.MSBuild ` + -find "MSBuild\**\Bin\MSBuild.exe" 2>$null | + Select-Object -First 1 + if ($found) { $msBuild = $found } + } +} + if (-not $msBuild) { Write-Host "ERROR: MSBuild not found." -ForegroundColor Red Write-Host "" diff --git a/server/2015Remote/2015RemoteDlg.cpp b/server/2015Remote/2015RemoteDlg.cpp index 3eb8d70..bf81fc6 100644 --- a/server/2015Remote/2015RemoteDlg.cpp +++ b/server/2015Remote/2015RemoteDlg.cpp @@ -5618,12 +5618,23 @@ VOID CMy2015RemoteDlg::MessageHandle(CONTEXT_OBJECT* ContextObject) break; } case TOKEN_TERMINAL_START: { // Linux PTY 终端 (WebView2 + xterm.js) - // 检查 WebView2 和 DLL,都满足则使用现代终端,否则退化到经典终端 - if (IsWebView2Available() && LoadTerminalModule()) { + // 三个前置条件,缺任何一个都回退到经典终端,并把原因贴到信息列表。 + // SYSTEM 场景:WebView2 不支持 LocalSystem token,会出现"窗口能弹但页面空白", + // 显式拦截一次,避免用户误以为是 bug。 + const char* fallbackReason = nullptr; + if (IsRunningAsSystem()) { + fallbackReason = "Modern Terminal does not support SYSTEM, falling back to classic"; + } else if (!IsWebView2Available()) { + fallbackReason = "WebView2 Runtime not installed, falling back to classic"; + } else if (!LoadTerminalModule()) { + fallbackReason = "TerminalModule.dll load failed, falling back to classic"; + } + + if (fallbackReason == nullptr) { g_2015RemoteDlg->SendMessage(WM_OPENTERMINALDIALOG, 0, (LPARAM)ContextObject); } else { - g_2015RemoteDlg->PostMessageA(WM_SHOWMESSAGE, - (WPARAM)new CharMsg("To use Modern Terminal - WebView2 and TerminalModule.dll are required"), NULL); + g_2015RemoteDlg->PostMessageA(WM_SHOWMESSAGE, + (WPARAM)new CharMsg(fallbackReason), NULL); g_2015RemoteDlg->SendMessage(WM_OPENSHELLDIALOG, 0, (LPARAM)ContextObject); } break; diff --git a/server/2015Remote/TerminalModuleLoader.h b/server/2015Remote/TerminalModuleLoader.h index 38dfdc6..a196461 100644 --- a/server/2015Remote/TerminalModuleLoader.h +++ b/server/2015Remote/TerminalModuleLoader.h @@ -136,6 +136,35 @@ inline bool IsTerminalModuleLoaded() return g_hTerminalModule != nullptr; } +// Check if current process is running as LocalSystem (S-1-5-18). +// 用途:WebView2 / msedgewebview2.exe 子进程拒绝在 SYSTEM token 下渲染(Microsoft +// 官方限制),此时 Modern Terminal 会打开但页面空白,需要回退到经典终端。 +// 结果缓存,因为进程 token 在生命周期内不会变。 +inline bool IsRunningAsSystem() +{ + static int cached = -1; + if (cached >= 0) return cached == 1; + + bool isSystem = false; + HANDLE hToken = nullptr; + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { + BYTE buf[256] = {}; + DWORD len = 0; + if (GetTokenInformation(hToken, TokenUser, buf, sizeof(buf), &len)) { + SID_IDENTIFIER_AUTHORITY ntAuth = SECURITY_NT_AUTHORITY; + PSID pSystemSid = nullptr; + if (AllocateAndInitializeSid(&ntAuth, 1, SECURITY_LOCAL_SYSTEM_RID, + 0, 0, 0, 0, 0, 0, 0, &pSystemSid)) { + isSystem = EqualSid(((TOKEN_USER*)buf)->User.Sid, pSystemSid) != FALSE; + FreeSid(pSystemSid); + } + } + CloseHandle(hToken); + } + cached = isSystem ? 1 : 0; + return isSystem; +} + // Check if WebView2 Runtime is installed (cached) inline bool IsWebView2Available() {