Skip to content

fix: Unity process matching now survives non-ASCII project paths on Windows - #1815

Merged
hatayama merged 2 commits into
feature/windows-v3-verification-integrationfrom
fix/windows-process-list-encoding
Jul 17, 2026
Merged

fix: Unity process matching now survives non-ASCII project paths on Windows#1815
hatayama merged 2 commits into
feature/windows-v3-verification-integrationfrom
fix/windows-process-list-encoding

Conversation

@hatayama

@hatayama hatayama commented Jul 16, 2026

Copy link
Copy Markdown
Owner

Summary

On Windows, Unity process matching fails for any project whose path contains non-ASCII characters (e.g. Japanese). listUnityProcessesWindows runs a Windows PowerShell 5.1 script (Get-CimInstance Win32_Process) and reads its stdout as UTF-8, but PowerShell 5.1 encodes redirected stdout with the OEM code page (CP932 on Japanese Windows). Non-ASCII path segments arrive as CP932 bytes, never match the UTF-8 normalized target path, and FindRunningUnityProcess always comes back empty.

Measured on a Japanese Windows 11 machine: the path segment 検証用 was delivered as the CP932 byte sequence 0x8C9F 0x8FD8 0x9770 instead of its UTF-8 encoding.

Impact

For any non-ASCII project path, all Unity process matching is broken:

  • uloop launch -q reports "No Unity process is running for this project." with Success:true / exit 0 while the editor keeps running (silent no-op)
  • uloop launch -r cannot find the process to restart
  • AlreadyRunning detection fails, so a plain uloop launch spawns a duplicate editor
  • uloop focus-window cannot resolve its target PID

Non-ASCII project paths are common on Japanese/Korean/Chinese Windows, so this has real user impact.

Fix

Transport each command line as Base64 over UTF-8 bytes inside the PowerShell script and decode it in the Go parser. The stdout stream becomes ASCII-only, so the console code page can no longer corrupt it.

$encodedCommandLine = [Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($commandLine))
Write-Output ("{0}|{1}" -f $process.ProcessId, $encodedCommandLine)

Why Base64 instead of [Console]::OutputEncoding = UTF8

  • Setting [Console]::OutputEncoding is known to throw IOException: The handle is invalid when the process has no attached console (a realistic condition for a CLI that is itself spawned detached), so it is less robust.
  • Base64 removes the encoding, quoting, and newline concerns in one move, and this codebase already uses the Base64 idiom for PowerShell boundaries (-EncodedCommand in the install/uninstall scripts).

Lines whose command field is not valid Base64 are skipped, consistent with how other malformed lines are handled.

Cross-check of other PowerShell output readers

Audited every place that parses PowerShell stdout:

  • cli/common/unityprocess/focus_windows.go (focus_unity_process_with_restore.ps1): stdout is a numeric window handle only (ASCII-safe) — not affected. Its captured stderr could contain localized CP932 error text on failure, but that only feeds error messages (cosmetic), not matching logic.
  • All other .Output() call sites run git / osascript / self-exec JSON — not affected.

Verification (Windows 11, Japanese locale, Unity 2022.3.62f3)

TDD, unit (Red -> Green):

  • New tests specify the Base64 contract: script content assertion, Base64 round-trip parsing including a Japanese path (test[1] 検証用), and skipping of non-Base64 lines (using the measured CP932 bytes). All 4 failed before the fix, all pass after.

E2E (Red, pre-fix build): project at ...\検証用エンコーディング\proj

  • launch -> Ready:true (PID 27128), then launch -q -> "No Unity process is running for this project.", Success:true, exit 0, process still alive

E2E (Green, fixed build):

  • launch -q -> Quit:true, PreviousProcessId:27128, "Unity process stopped.", process actually terminated
  • launch -> Ready:true (PID 29960), second launch -> AlreadyRunning:true
  • ASCII regression: separate ASCII-path project -> AlreadyRunning:true and launch -q -> PreviousProcessId returned, process stopped
  • Isolation: quitting the ASCII project's editor left the Japanese-path editor and an unrelated editor untouched
  • go test ./... across all four modules: only the pre-existing Windows-incompatible baseline failures (launch /usr/bin/true fixture, TCP-only fixture, git fixture); common module fully green

Out of scope (recorded separately)

  • launch -q returning Success:true / exit 0 when no process is found is itself questionable (it is what made this bug silent), but that is an intentional-looking behavior and is left as a separate design question.
  • Localized CP932 stderr from the focus scripts rendering as mojibake in error messages (cosmetic).

Review in cubic

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 5e6a7c64-e751-4467-8cf9-8835034a1fa4

📥 Commits

Reviewing files that changed from the base of the PR and between d578c38 and 0ec9d67.

📒 Files selected for processing (2)
  • cli/common/unityprocess/process.go
  • cli/common/unityprocess/process_test.go

📝 Walkthrough

Walkthrough

Windows PowerShell process discovery now Base64-encodes UTF-8 command lines, while Go decodes them before identifying Unity processes and extracting project paths. Tests cover encoded input, non-ASCII paths, invalid payloads, and script generation.

Changes

Windows process transport

Layer / File(s) Summary
PowerShell command-line encoding
cli/common/unityprocess/process.go, cli/common/unityprocess/process_test.go
Windows process listing emits `pid
Go command-line decoding and validation
cli/common/unityprocess/process.go, cli/common/unityprocess/process_test.go
The parser decodes command lines before Unity detection and project-path extraction; tests cover encoded commands, non-ASCII paths, and invalid Base64 input.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 63.64% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and accurately summarizes the main Windows non-ASCII Unity process-matching fix.
Description check ✅ Passed The description is directly related to the changeset and explains the bug, fix, and verification in detail.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/windows-process-list-encoding

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

hatayama added 2 commits July 17, 2026 20:57
Expose the PowerShell script that lists Unity processes as
windowsUnityProcessListScript() so its content can be unit tested,
mirroring the existing focus script builders. No behavior change.
Windows PowerShell 5.1 encodes redirected stdout with the OEM code
page (CP932 on Japanese Windows), so the Unity process list script
delivered non-ASCII project paths as corrupted bytes that never
matched the UTF-8 target path. FindRunningUnityProcess then missed
running editors, breaking launch -q / launch -r / AlreadyRunning
detection and focus targeting for any non-ASCII project path, with
launch -q silently reporting success while doing nothing.

Encode each command line as Base64 over UTF-8 bytes inside the
PowerShell script and decode it in the Go parser, keeping the stdout
stream ASCII-only regardless of the console code page. This follows
the existing -EncodedCommand precedent in the installer scripts.
@hatayama
hatayama force-pushed the fix/windows-process-list-encoding branch from e17df95 to 0ec9d67 Compare July 17, 2026 11:57
@hatayama
hatayama merged commit 078433e into feature/windows-v3-verification-integration Jul 17, 2026
5 checks passed
@hatayama
hatayama deleted the fix/windows-process-list-encoding branch July 17, 2026 12:05
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.

1 participant