From 985792a83b7f1fdfc2bd661f8754d4f018b3dce8 Mon Sep 17 00:00:00 2001 From: Daniel Han Date: Fri, 12 Jun 2026 23:57:30 -0700 Subject: [PATCH] Installer: drop redundant -WindowStyle Hidden from the Windows launcher VBS (#6284) * Installer: drop redundant -WindowStyle Hidden from the Windows launcher VBS The desktop / Start Menu shortcut launches Studio through a generated launch-studio.vbs that runs: shell.Run "powershell ... -WindowStyle Hidden -File launch-studio.ps1", 0, False The second argument to shell.Run is intWindowStyle 0 (hidden), so WScript already launches the child windowless. The child -WindowStyle Hidden is therefore redundant: dropping it keeps the launcher hidden and behaviour identical, while removing the WScript-spawns-hidden-ExecutionPolicy-Bypass PowerShell token combination that antivirus heuristics weight. That shape was reported as a Kaspersky HEUR:Trojan.VBS.Agent false positive during install. Adds tests/studio/install/test_launch_studio_launcher.py to stop the flag from being reintroduced and to assert the launcher stays windowless via shell.Run(cmd, 0, False). * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --------- Co-authored-by: Daniel Han Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- install.ps1 | 4 +- .../install/test_launch_studio_launcher.py | 50 +++++++++++++++++++ 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 tests/studio/install/test_launch_studio_launcher.py diff --git a/install.ps1 b/install.ps1 index 5baf76b9fa..88939ce627 100644 --- a/install.ps1 +++ b/install.ps1 @@ -799,9 +799,11 @@ exit 0 # even when install.ps1 is executed from PowerShell 7. $utf8Bom = New-Object System.Text.UTF8Encoding($true) [System.IO.File]::WriteAllText($launcherPs1, $launcherContent, $utf8Bom) + # shell.Run(cmd, 0, ...) already hides the window, so -WindowStyle Hidden + # is redundant; omitting it trims an AV-heuristic token (Kaspersky FP). $vbsContent = @" Set shell = CreateObject("WScript.Shell") -cmd = "powershell -NoProfile -ExecutionPolicy Bypass -WindowStyle Hidden -File ""$launcherPs1""" +cmd = "powershell -NoProfile -ExecutionPolicy Bypass -File ""$launcherPs1""" shell.Run cmd, 0, False "@ # WSH handles UTF-16LE reliably for .vbs files with non-ASCII paths. diff --git a/tests/studio/install/test_launch_studio_launcher.py b/tests/studio/install/test_launch_studio_launcher.py new file mode 100644 index 0000000000..8ea9ca7d80 --- /dev/null +++ b/tests/studio/install/test_launch_studio_launcher.py @@ -0,0 +1,50 @@ +"""Guard install.ps1's launch-studio.vbs against re-introducing the AV-heuristic +shape: a WScript .vbs spawning a hidden, ExecutionPolicy-Bypass PowerShell.""" + +import re +from pathlib import Path + +import pytest + +REPO_ROOT = Path(__file__).resolve().parents[3] +INSTALL_PS1 = REPO_ROOT / "install.ps1" + + +def _vbs_block() -> str: + text = INSTALL_PS1.read_text(encoding = "utf-8") + m = re.search(r'\$vbsContent\s*=\s*@"\r?\n(.*?)\r?\n"@', text, re.S) + assert m, "could not locate the $vbsContent here-string in install.ps1" + return m.group(1) + + +def test_install_ps1_present(): + assert INSTALL_PS1.is_file(), f"missing {INSTALL_PS1}" + + +def test_vbs_does_not_pass_windowstyle_hidden(): + vbs = _vbs_block() + assert "-WindowStyle Hidden" not in vbs, ( + "launch-studio.vbs must not pass -WindowStyle Hidden to PowerShell: the " + "window is already hidden by shell.Run(cmd, 0, False); the redundant flag " + "only adds the hidden-PowerShell token that AV heuristics flag." + ) + + +def test_vbs_stays_windowless_via_shell_run(): + vbs = _vbs_block() + assert re.search(r"shell\.Run\s+cmd\s*,\s*0\s*,\s*False", vbs), ( + "launcher must remain windowless via shell.Run(cmd, 0, False) " + "(intWindowStyle 0 = hidden)." + ) + + +def test_vbs_keeps_bypass_and_file_invocation(): + # Bypass lets the unsigned local .ps1 run under the default Restricted policy. + vbs = _vbs_block() + assert "-ExecutionPolicy Bypass" in vbs + assert "-File" in vbs + assert "powershell" in vbs + + +if __name__ == "__main__": + raise SystemExit(pytest.main([__file__, "-v"]))