Skip to content

Windows: add run_tests.ps1 + fix SxS mozglue launch failure on clean systems - #624

Draft
koopatroopa787 wants to merge 3 commits into
daijro:mainfrom
koopatroopa787:windows-service-tests
Draft

Windows: add run_tests.ps1 + fix SxS mozglue launch failure on clean systems#624
koopatroopa787 wants to merge 3 commits into
daijro:mainfrom
koopatroopa787:windows-service-tests

Conversation

@koopatroopa787

@koopatroopa787 koopatroopa787 commented May 25, 2026

Copy link
Copy Markdown

Closes #622.

What this PR does

Two separate problems blocked Camoufox from working on Windows. Both are fixed here.


1. run_tests.ps1 — PowerShell equivalent of run_tests.sh

service-tester/run_tests.sh is a Bash script and cannot run on Windows.
This PR adds service-tester/run_tests.ps1, a full PowerShell port that:

  • Mirrors every flag: -BrowserVersion, -ProfileCount, -Proxies, -Headful, -NoCert, -SaveCert, -Binary
  • Supports all three binary modes: local | fetched | both (default: both)
  • Auto-detects a locally compiled Windows build at ../camoufox-*/obj-*-windows-msvc/dist/bin/camoufox.exe
  • Creates and manages a .venv Python virtual environment inside service-tester/
  • Builds the camoufox wheel from pythonlib/ and installs it into the venv
  • Sets [Console]::OutputEncoding = UTF8 and $env:PYTHONIOENCODING=utf-8 so Unicode output renders correctly
  • Uses [IO.Path]::Combine() throughout for PowerShell 5.x / Windows PowerShell compatibility

Usage:

.\run_tests.ps1                                                    # both phases, official/stable
.\run_tests.ps1 -BrowserVersion official/prerelease/146.0.1-beta.50 -Headful
.\run_tests.ps1 -Binary local                                      # only locally compiled build
.\run_tests.ps1 -Binary fetched -ProfileCount 3

2. SxS mozglue launch failure — investigation and fix

Symptom: camoufox.exe exits immediately with:

The application has failed to start because its side-by-side configuration is incorrect.

Root cause (confirmed via PE resource inspection and SxS tracing):

camoufox.exe embeds a manifest (PE resource ID 1) declaring mozglue as a Win32 SxS dependency. When no mozglue entry exists in the global C:\Windows\WinSxS store (i.e. no prior Firefox install) and no private mozglue.manifest file sits alongside the exe, the Windows SxS loader fails.

Discovery during testing — AppContainer capability SID interaction:

Thorough end-to-end testing uncovered a second, deeper failure mode specific to Windows machines with Microsoft Edge (or Chrome) installed. Edge adds an AppContainer Capability SID (S-1-15-3-*) to AppData\Local with (OI)(CI) inheritance flags, which propagates to every file extracted under AppData\Local (the default camoufox install location).

When the entire ancestor directory chain contains this SID, Windows switches the SxS loader into strict mode: any failed SxS dependency lookup becomes a hard fatal error, and the mozglue.manifest private-assembly file is not consulted.

Testing matrix (this machine — Edge installed):

Path Exe has AppContainer SID Result without manifest
C:\cf_test ✅ PASS
Documents\cf_test ✅ PASS
AppData\Local\Temp\cf_test ✗ (Temp breaks inheritance) ✅ PASS
AppData\Local\cf_test ✓ (inherited from parent) ❌ FAIL
AppData\Roaming\cf_test ❌ FAIL

Adding mozglue.manifest fixes the failure on machines WITHOUT the SID issue (i.e. no Edge/Chrome installed, or Windows versions that don't propagate the SID). On machines WITH Edge installed, the manifest alone is insufficient — the underlying cause is the install path sitting within the capability-SID-propagating AppData\Local subtree.

This PR's fix (partial): install_versioned() now writes mozglue.manifest alongside camoufox.exe after extraction on Windows. This resolves the issue on machines without the AppContainer SID propagation (clean Windows, no prior Edge run, or machines where AppData\Local does not carry the SID).

Known limitation: On machines where Edge has added its capability SID to AppData\Local (most Windows 10/11 installations where Edge has been opened at least once), the proper fix requires either:

  • Changing the camoufox install directory to a path outside AppData\Local/AppData\Roaming (e.g. ~/.camoufox or a user-chosen path)
  • Or removing the mozglue SxS dependency from the binary at build time

Both of these are out of scope for this PR and should be tracked separately.


3. Additional Windows fixes in service-tester/

File Fix
_bundle.py Use esbuild.cmd on Windows instead of esbuild (the Unix shell script) — prevents WinError 193 [not a valid Win32 application]
run_tests.py Call sys.stdout.reconfigure(encoding="utf-8", errors="replace") on Windows — prevents UnicodeEncodeError on box-drawing characters (U+2500 ) used in progress output

Known limitation (not in scope)

Running in headless mode on the current Windows binary triggers a STATUS_BREAKPOINT (0x80000003) crash — a debugger breakpoint left in the build. This is tracked separately in #614 and requires an upstream binary fix. The run_tests.ps1 script works correctly in headful mode (-Headful) with the current binary.

@KittisakPh

Copy link
Copy Markdown

thx u very much <3

@koopatroopa787

Copy link
Copy Markdown
Author

Progress update — Windows testing run

Pushed the initial implementation and ran it through all three -Binary scenarios on Windows 11 (build 26200). Here's a full account of what was found.


What's been added / fixed

File Change
service-tester/run_tests.ps1 New — PowerShell equivalent of run_tests.sh
service-tester/_bundle.py Fix — use esbuild.cmd on Windows (WinError 193 otherwise)
service-tester/run_tests.py Fix — reconfigure stdout/stderr to UTF-8 on win32 (CP1252 can't encode U+2500 box-drawing chars)

Scenario results

-Binary local (no local build present)

  • npm deps installed, venv created, wheel built and installed
  • Binary glob (../camoufox-*/obj-*-windows-msvc/dist/bin/camoufox.exe) ran, found nothing
  • Correctly exited with: ERROR: -Binary local requested but no local build found

-Binary fetched ✅ up to browser launch

  • Full env setup completed
  • camoufox v135.0.1-beta.24 downloaded (530 MB) and installed
  • UTF-8 fix confirmed working — Unicode separators rendered correctly
  • Blocked at browser launch — see below

-Binary both (default, no local build)

  • Phase 1 skipped gracefully with notice
  • Phase 2 ran, hit same binary issue
  • Combined result block printed correctly, exit code 1

Blocker: Windows binary won't launch on clean installs

The binary fails before execution with:

The application has failed to start because its side-by-side configuration is incorrect.

Event log confirms:

Activation context generation failed for camoufox.exe.
Dependent Assembly mozglue,language="*",type="win32",version="1.0.0.0" could not be found.

Root cause: camoufox.exe embeds a manifest declaring mozglue as a Win32 SxS assembly dependency. The Windows zip package ships mozglue.dll (with a correct embedded assembly manifest at resource ID 2), but does not ship an external mozglue.manifest file. On a clean system with no prior Firefox or Visual Studio install, Windows cannot resolve the private assembly and the binary never starts.

This is different from the headless crash in #614 — that issue hits systems where the binary does launch (because mozglue is already registered globally via a Firefox or VS install). Our system has neither, so we hit the earlier failure.

What Firefox's installer does: it places mozglue.manifest alongside mozglue.dll in the install directory. The file content (from Firefox source) is:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity version="1.0.0.0" name="mozglue" type="win32"/>
<file name="mozglue.dll"/>
</assembly>

Suggested packaging fix — add mozglue.manifest to package-windows in the Makefile:

package-windows:
    python3 scripts/package.py windows \
        --includes \
            settings/chrome.css \
            settings/camoucfg.jvv \
            settings/properties.json \
            ~/.mozbuild/vs/VC/Redist/MSVC/14.38.33135/$(vcredist_arch)/Microsoft.VC143.CRT/*.dll \
            $(cf_source_dir)/obj-$(moz_target)/dist/bin/mozglue.manifest

We did test placing the manifest manually — the binary still failed on this specific system (Windows 11 24H2, build 26200), which may be due to stricter SxS resolution in that build or a Windows activation context cache. Happy to retest once a new Windows binary is available.


References

…ster

- Add service-tester/run_tests.ps1: PowerShell equivalent of run_tests.sh,
  mirrors all three binary modes (local | fetched | both), auto-detects
  Windows build at obj-*-windows-msvc/dist/bin/camoufox.exe, handles
  Windows venv paths (.venv\Scripts\python.exe), and sets UTF-8 console
  encoding so Unicode box-drawing characters render correctly

- Fix service-tester/_bundle.py: use esbuild.cmd on Windows instead of
  the Unix shell script esbuild (WinError 193 otherwise)

- Fix service-tester/run_tests.py: reconfigure stdout/stderr to UTF-8 on
  win32 to prevent UnicodeEncodeError from box-drawing characters in
  console output (CP1252 default does not support U+2500)

Tested on Windows 11 (build 26200) — all three -Binary scenarios
(local/fetched/both) behave correctly at the script level. Browser launch
is currently blocked by a missing mozglue.manifest in the Windows zip
package (SxS resolution fails on clean installs); documented in PR.
@koopatroopa787
koopatroopa787 force-pushed the windows-service-tests branch from 10550e6 to 2dc1abc Compare May 25, 2026 23:31
@KittisakPh

Copy link
Copy Markdown

pls fix for us Window Community waiting for this. never give up Bro!!!
@icepaq @koopatroopa787

…launch failure

camoufox.exe embeds a manifest (resource ID 1) that declares mozglue as a
Win32 side-by-side (SxS) assembly dependency.  The Firefox installer registers
mozglue in the global WinSxS store; the portable zip does not.  On a clean
Windows machine (no prior Firefox or Visual Studio install) this causes every
camoufox.exe launch to fail immediately with:

    The application has failed to start because its side-by-side configuration
    is incorrect.

Root cause (confirmed via PE resource inspection and SxS activation-context
tracing):
  - camoufox.exe resource ID 1 contains a manifest that lists mozglue as a
    dependent assembly with processorArchitecture="x86" (or "amd64").
  - Windows SxS searches for the private assembly in this order:
      1. <appdir>\mozglue\mozglue.manifest  (subdirectory form)
      2. <appdir>\mozglue.manifest          (flat-file form)
  - Neither file exists in the extracted zip, so the search fails and the
    process terminates before any user code runs.

Fix: after extracting the zip in install_versioned(), write a minimal
mozglue.manifest next to camoufox.exe.  The manifest content is identical
to the one shipped in Firefox source (mozglue/build/mozglue.dll.manifest).
This satisfies the SxS private-assembly lookup without touching the system
WinSxS store.

Important: only the flat-file form (mozglue.manifest directly in the install
dir) must be used.  If a mozglue\ *subdirectory* is also present Windows
finds it first, fails because the DLL is absent from it, and does NOT fall
back to the flat file -- causing the same error.
@koopatroopa787 koopatroopa787 changed the title Add Windows service test script (run_tests.ps1) Windows: add run_tests.ps1 + fix SxS mozglue launch failure on clean systems May 26, 2026
@KittisakPh

Copy link
Copy Markdown

@icepaq how it work bro we will wating for this

@KittisakPh

Copy link
Copy Markdown

@daijro this window 🙏🙏🙏🙏🙏🙏

@KittisakPh

Copy link
Copy Markdown

@daijro @icepaq
I'm so disappointed, brother. You've updated the Readme files, but you've ignored the fact that Windows still can't use the new version. We've been waiting since January, and now it's almost halfway through, and Windows still can't do anything. Please, just get it over with, brother.

@daijro

daijro commented Jun 5, 2026

Copy link
Copy Markdown
Owner

@daijro @icepaq I'm so disappointed, brother. You've updated the Readme files, but you've ignored the fact that Windows still can't use the new version. We've been waiting since January, and now it's almost halfway through, and Windows still can't do anything. Please, just get it over with, brother.

@KittisakPh Hi, I'd be happy to merge this in once a fix for the current crashing/limitations is implemented and tests are passing. Atm I'm not active in the development of this project, and I don't use Windows enough to help out

@KittisakPh

Copy link
Copy Markdown

Okay, thank you for the explanation. Thank you. I have a little more hope now. Thinking of you, my god
@daijro

@GleckusZeroFive

Copy link
Copy Markdown

Adding a data point on the SxS part, since I ran into this independently and the external-manifest route didn't work here.

Environment: Windows 11 Pro 10.0.26200, camoufox 135.0.1-beta.24, python lib, clean system (no prior Firefox / VS install).

The external mozglue.manifest did not resolve it for me. I tried the flat-file form from this PR, plus variants with language="*", with and without BOM, and with processorArchitecture set. camoufox.exe still exited immediately — spawn UNKNOWN via Playwright, "side-by-side configuration is incorrect" when launched directly.

Comparing what the exe asks for against what the DLL offers, two things appear to be at play:

  1. The embedded manifest in camoufox.exe requests mozglue with language="*". The manifest generated by this PR has no language attribute (i.e. neutral), so the identities don't match on a strict resolver. mozglue.dll's own embedded manifest is neutral as well.
  2. As @e-orlov notes in camoufox.exe fails to launch on Windows: SxS manifest declares mozglue as win32 assembly dependency #650, an external .manifest is merged with the embedded one rather than replacing it — so it cannot cancel the existing <dependency> regardless of its contents.

That would explain why this passes on your box but users keep reporting the launch failure is still there.

What worked here: patching the embedded manifest inside camoufox.exe — blanking the <dependency>…</dependency> block that references mozglue with spaces, in place, so the PE size is unchanged. The manifest stays valid XML, the SxS dependency is gone entirely, and Windows loads mozglue.dll through the normal DLL search from the exe directory. Same conclusion @e-orlov reached in #650.

Stable here for a couple of days of real use — stealth checks pass (navigator.webdriver false, no cdc_ leaks), live Cloudflare traffic works.

To be clear on scope: the proper upstream fix is the manifest at build time (<file name="mozglue.dll"/> instead of the <dependency> block). Patching after fetch is a workaround for the prebuilt binaries the python lib downloads — but that is the path most Windows users are on.

Happy to push it as a commit here if useful: ~20 lines, idempotent, and it slots in at the same point in install_versioned() where _ensure_mozglue_manifest() is called now.

Diagnosis and patch worked out with Claude Opus 4.8.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Help Wanted - Windows Support and Service Tests

4 participants