fix(infra): resolve Windows port inspection tools

This commit is contained in:
Vincent Koc
2026-06-21 12:22:18 +02:00
parent a70b34a3cb
commit c4facb2bb3
2 changed files with 33 additions and 17 deletions
+16 -5
View File
@@ -15,6 +15,11 @@ import type {
PortUsage,
PortUsageStatus,
} from "./ports-types.js";
import {
getWindowsPowerShellExePath,
getWindowsSystem32ExePath,
getWindowsWmicExePath,
} from "./windows-install-roots.js";
type CommandResult = {
stdout: string;
@@ -495,7 +500,13 @@ function parseNetstatConnections(output: string, port: number): PortConnection[]
}
async function resolveWindowsImageName(pid: number): Promise<string | undefined> {
const res = await runCommandSafe(["tasklist", "/FI", `PID eq ${pid}`, "/FO", "LIST"]);
const res = await runCommandSafe([
getWindowsSystem32ExePath("tasklist.exe"),
"/FI",
`PID eq ${pid}`,
"/FO",
"LIST",
]);
if (res.code !== 0) {
return undefined;
}
@@ -512,7 +523,7 @@ async function resolveWindowsImageName(pid: number): Promise<string | undefined>
async function resolveWindowsCommandLine(pid: number): Promise<string | undefined> {
const powershell = await runCommandSafe([
"powershell",
getWindowsPowerShellExePath(),
"-NoProfile",
"-Command",
`(Get-CimInstance Win32_Process -Filter "ProcessId = ${pid}" | Select-Object -ExpandProperty CommandLine)`,
@@ -525,7 +536,7 @@ async function resolveWindowsCommandLine(pid: number): Promise<string | undefine
}
const wmic = await runCommandSafe([
"wmic",
getWindowsWmicExePath(),
"process",
"where",
`ProcessId=${pid}`,
@@ -551,7 +562,7 @@ async function readWindowsListeners(
port: number,
): Promise<{ listeners: PortListener[]; detail?: string; errors: string[] }> {
const errors: string[] = [];
const res = await runCommandSafe(["netstat", "-ano", "-p", "tcp"]);
const res = await runCommandSafe([getWindowsSystem32ExePath("netstat.exe"), "-ano", "-p", "tcp"]);
if (res.code !== 0) {
if (res.error) {
errors.push(res.error);
@@ -587,7 +598,7 @@ async function readWindowsEstablishedConnections(
port: number,
): Promise<{ connections: PortConnection[]; detail?: string; errors: string[] }> {
const errors: string[] = [];
const res = await runCommandSafe(["netstat", "-ano", "-p", "tcp"]);
const res = await runCommandSafe([getWindowsSystem32ExePath("netstat.exe"), "-ano", "-p", "tcp"]);
if (res.code !== 0) {
if (res.error) {
errors.push(res.error);
+17 -12
View File
@@ -3,6 +3,11 @@ import net from "node:net";
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from "vitest";
import { stripAnsi } from "../../packages/terminal-core/src/ansi.js";
import { mockProcessPlatform } from "../test-utils/vitest-spies.js";
import {
getWindowsPowerShellExePath,
getWindowsSystem32ExePath,
getWindowsWmicExePath,
} from "./windows-install-roots.js";
const runCommandWithTimeoutMock = vi.hoisted(() => vi.fn());
@@ -422,7 +427,7 @@ describe("inspectPortUsage on Windows", () => {
setPlatform("win32");
runCommandWithTimeoutMock.mockImplementation(async (argv: string[]) => {
const [command] = argv;
if (command === "netstat") {
if (command === getWindowsSystem32ExePath("netstat.exe")) {
return {
stdout:
" TCP 127.0.0.1:50123 127.0.0.1:18789 ESTABLISHED 4242\r\n" +
@@ -431,10 +436,10 @@ describe("inspectPortUsage on Windows", () => {
code: 0,
};
}
if (command === "tasklist") {
if (command === getWindowsSystem32ExePath("tasklist.exe")) {
return { stdout: "Image Name: node.exe\r\n", stderr: "", code: 0 };
}
if (command === "powershell") {
if (command === getWindowsPowerShellExePath()) {
return {
stdout:
'"C:\\Program Files\\nodejs\\node.exe" C:\\Users\\me\\AppData\\Roaming\\npm\\node_modules\\openclaw\\dist\\index.js logs --follow\r\n',
@@ -460,17 +465,17 @@ describe("inspectPortUsage on Windows", () => {
setPlatform("win32");
runCommandWithTimeoutMock.mockImplementation(async (argv: string[]) => {
const [command] = argv;
if (command === "netstat") {
if (command === getWindowsSystem32ExePath("netstat.exe")) {
return {
stdout: " TCP 127.0.0.1:18789 0.0.0.0:0 LISTENING 4242\r\n",
stderr: "",
code: 0,
};
}
if (command === "tasklist") {
if (command === getWindowsSystem32ExePath("tasklist.exe")) {
return { stdout: "Image Name: node.exe\r\n", stderr: "", code: 0 };
}
if (command === "powershell") {
if (command === getWindowsPowerShellExePath()) {
return {
stdout:
'"C:\\Program Files\\nodejs\\node.exe" C:\\Users\\me\\AppData\\Roaming\\npm\\node_modules\\openclaw\\dist\\index.js gateway run\r\n',
@@ -496,7 +501,7 @@ describe("inspectPortUsage on Windows", () => {
setPlatform("win32");
runCommandWithTimeoutMock.mockImplementation(async (argv: string[]) => {
const [command] = argv;
if (command === "netstat") {
if (command === getWindowsSystem32ExePath("netstat.exe")) {
return {
stdout:
" TCP 127.0.0.1:187890 0.0.0.0:0 LISTENING 9000\r\n" +
@@ -517,20 +522,20 @@ describe("inspectPortUsage on Windows", () => {
setPlatform("win32");
runCommandWithTimeoutMock.mockImplementation(async (argv: string[]) => {
const [command] = argv;
if (command === "netstat") {
if (command === getWindowsSystem32ExePath("netstat.exe")) {
return {
stdout: " TCP 127.0.0.1:18789 0.0.0.0:0 LISTENING 4242\r\n",
stderr: "",
code: 0,
};
}
if (command === "tasklist") {
if (command === getWindowsSystem32ExePath("tasklist.exe")) {
return { stdout: "Image Name: node.exe\r\n", stderr: "", code: 0 };
}
if (command === "powershell") {
if (command === getWindowsPowerShellExePath()) {
return { stdout: "", stderr: "access denied", code: 1 };
}
if (command === "wmic") {
if (command === getWindowsWmicExePath()) {
return {
stdout: "CommandLine=node.exe C:\\openclaw\\dist\\index.js gateway run\r\n",
stderr: "",
@@ -544,6 +549,6 @@ describe("inspectPortUsage on Windows", () => {
expect(result.listeners[0]?.commandLine).toContain("openclaw");
const commandNames = runCommandWithTimeoutMock.mock.calls.map(([argv]) => argv[0]);
expect(commandNames).toContain("wmic");
expect(commandNames).toContain(getWindowsWmicExePath());
});
});