fix: use Get-NetTCPConnection for locale-independent port lookup

The netstat-based parser matched the literal English "LISTENING"
state string, which is translated on non-English Windows (e.g.
"ABHÖREN", "ÉCOUTE", "ESCUTANDO"). On those systems the regex matched
zero lines, so killProcessOnPort silently did nothing -- fail-open,
not a regression, but ineffective for the exact users the fix targets.

Replace it with `Get-NetTCPConnection -State Listen -LocalPort <port>`,
which reads the same underlying WinNT API netstat's display layer
translates, so it's unaffected by OS display language. Verified
against a real listening port on this machine (matched the actual
owning PID).

Also fixed a stale duplicate of the "killProcessOnPort is a no-op on
Windows" comment left behind in server/index.js.
This commit is contained in:
Sérgio Pedro
2026-08-12 11:50:39 +01:00
parent d06329bca1
commit a1a1cfb93d
3 changed files with 29 additions and 24 deletions
+16 -6
View File
@@ -55,15 +55,25 @@ export const createOpenCodeLifecycleRuntime = (deps) => {
const killProcessOnPortWin32 = (port) => {
try {
const result = spawnSync('netstat', ['-ano'], { encoding: 'utf8', timeout: 5000, windowsHide: true });
// Get-NetTCPConnection reads the same locale-independent WinNT API
// netstat's display layer translates (e.g. "LISTENING" renders as
// "ABHÖREN"/"ÉCOUTE"/"ESCUTANDO" on non-English Windows), so this
// works regardless of the OS display language.
const result = spawnSync(
'powershell',
[
'-NoProfile',
'-NonInteractive',
'-Command',
`Get-NetTCPConnection -State Listen -LocalPort ${Number.parseInt(port, 10)} -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess`,
],
{ encoding: 'utf8', timeout: 5000, windowsHide: true }
);
const output = result.stdout || '';
const myPid = process.pid;
const listeningPidPattern = /^\s*TCP\s+\S*:(\d+)\s+\S+\s+LISTENING\s+(\d+)\s*$/gim;
const pids = new Set();
let match;
while ((match = listeningPidPattern.exec(output)) !== null) {
if (Number.parseInt(match[1], 10) !== port) continue;
const pid = Number.parseInt(match[2], 10);
for (const line of output.split(/\r?\n/)) {
const pid = Number.parseInt(line.trim(), 10);
if (pid && pid !== myPid) pids.add(pid);
}
for (const pid of pids) {