From c8414cb0cc3d26d74b2c7ab35d0e26871b10f40a Mon Sep 17 00:00:00 2001 From: Aksel Date: Tue, 28 Jan 2025 21:24:02 +0100 Subject: [PATCH 1/2] Use SIGTERM instead of SIGKILL when terminating old processes This gives the running application room to exit gracefully instead of being forcefully closed. --- src/watch/Watch.hx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/watch/Watch.hx b/src/watch/Watch.hx index e1e4049..05140a5 100644 --- a/src/watch/Watch.hx +++ b/src/watch/Watch.hx @@ -220,7 +220,7 @@ function killAll(tree: Map>, callback: (error: Option) - tree.get(pid).iter(pidpid -> { final isKilled = killed.get(pidpid) ?? false; if (!isKilled) { - switch Process.killPid(pidpid, SIGKILL) { + switch Process.killPid(pidpid, SIGTERM) { case Ok(_): killed.set(pidpid, true); case Error(e): @@ -228,7 +228,7 @@ function killAll(tree: Map>, callback: (error: Option) - } }); if (!(killed.get(pid) ?? false)) { - switch Process.killPid(pid, SIGKILL) { + switch Process.killPid(pid, SIGTERM) { case Ok(_): killed.set(pid, true); case Error(e): @@ -454,4 +454,4 @@ function register() { }); }); loop.loop(); -} \ No newline at end of file +} From d1bf4da70dfbeb798a75b896ba0453c9b8ee4d7b Mon Sep 17 00:00:00 2001 From: jefvel Date: Sat, 1 Feb 2025 15:28:50 +0100 Subject: [PATCH 2/2] Get child process pids for process tree in windows using the wmic command --- src/watch/Watch.hx | 53 ++++++++++++++++++++++++++++++---------------- 1 file changed, 35 insertions(+), 18 deletions(-) diff --git a/src/watch/Watch.hx b/src/watch/Watch.hx index 05140a5..6018877 100644 --- a/src/watch/Watch.hx +++ b/src/watch/Watch.hx @@ -177,9 +177,28 @@ function runCommand(command: String) { final pidsToProcess = [pid => true]; buildProcessTree(pid, tree, pidsToProcess, parentPid -> { // Get processes with parent pid - final psargs = '-o pid --no-headers --ppid $parentPid'; - final ps = new sys.io.Process('ps $psargs'); - ps; + var pids:Array = null; + var result:sys.io.Process = null; + if (Sys.systemName() == "Windows") { + final psargs = 'process where (ParentProcessId=${parentPid}) get ProcessId'; + final args = 'cmd.exe /c wmic $psargs'; + result = new sys.io.Process(args); + if (result.exitCode() == 0) { + var pidResult = result.stdout.readAll().toString(); + var pidStrings = pidResult.split("\n").slice(1); // Remove first line ("ProcessId") + pids = pidStrings.map(pidString -> Std.parseInt(pidString)).filter(p -> p != null); + } + } else { + final psargs = '-o pid --no-headers --ppid $parentPid'; + result = new sys.io.Process('ps $psargs'); + if (result.exitCode() == 0) { + pids = [Std.parseInt(result.stdout.readAll().toString())]; + } + } + + result?.close(); + + return pids; }, () -> { killAll(tree, _ -> cb()); }); @@ -192,25 +211,23 @@ function runCommand(command: String) { } } -function buildProcessTree(parentPid: Int, tree: Map>, pidsToProcess: Map, getChildPpid: (pid: Int) -> sys.io.Process, cb:() -> Void) { - final result = getChildPpid(parentPid); - if (result.exitCode() == 0) { - pidsToProcess.remove(parentPid); - final pid = Std.parseInt(result.stdout.readAll().toString()); - final children = tree.get(parentPid) ?? []; - if (!children.has(pid)) { - children.push(pid); - } - tree.set(parentPid, children); - tree.set(pid, []); - pidsToProcess.set(pid, true); - buildProcessTree(pid, tree, pidsToProcess, getChildPpid, cb); +function buildProcessTree(parentPid: Int, tree: Map>, pidsToProcess: Map, getChildPpid: (pid: Int) -> Array, cb:() -> Void) { + final childPids = getChildPpid(parentPid); + if (childPids != null && childPids.length > 0) { + pidsToProcess.remove(parentPid); + for (pid in childPids) { + final children = tree.get(parentPid) ?? []; + if (!children.has(pid)) { + children.push(pid); + } + tree.set(parentPid, children); + pidsToProcess.set(pid, true); + buildProcessTree(pid, tree, pidsToProcess, getChildPpid, cb); + } } else { pidsToProcess.remove(parentPid); cb(); } - - result.close(); } function killAll(tree: Map>, callback: (error: Option) -> Void) {