|
@@ -1,12 +1,35 @@
|
|
|
package process
|
|
|
|
|
|
-import "os"
|
|
|
+import (
|
|
|
+ "os"
|
|
|
+
|
|
|
+ "golang.org/x/sys/windows"
|
|
|
+)
|
|
|
|
|
|
// Alive returns true if process with a given pid is running.
|
|
|
func Alive(pid int) bool {
|
|
|
- _, err := os.FindProcess(pid)
|
|
|
-
|
|
|
- return err == nil
|
|
|
+ h, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, uint32(pid))
|
|
|
+ if err != nil {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ var c uint32
|
|
|
+ err = windows.GetExitCodeProcess(h, &c)
|
|
|
+ _ = windows.CloseHandle(h)
|
|
|
+ if err != nil {
|
|
|
+ // From the GetExitCodeProcess function (processthreadsapi.h) API docs:
|
|
|
+ // https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getexitcodeprocess
|
|
|
+ //
|
|
|
+ // The GetExitCodeProcess function returns a valid error code defined by the
|
|
|
+ // application only after the thread terminates. Therefore, an application should
|
|
|
+ // not use STILL_ACTIVE (259) as an error code (STILL_ACTIVE is a macro for
|
|
|
+ // STATUS_PENDING (minwinbase.h)). If a thread returns STILL_ACTIVE (259) as
|
|
|
+ // an error code, then applications that test for that value could interpret it
|
|
|
+ // to mean that the thread is still running, and continue to test for the
|
|
|
+ // completion of the thread after the thread has terminated, which could put
|
|
|
+ // the application into an infinite loop.
|
|
|
+ return c == uint32(windows.STATUS_PENDING)
|
|
|
+ }
|
|
|
+ return true
|
|
|
}
|
|
|
|
|
|
// Kill force-stops a process.
|