func IsProcessRunning(pid uint) (bool, error) { hProcess, err := wrappers.OpenProcess(wrappers.SYNCHRONIZE, false, uint32(pid)) if err == wrappers.ERROR_INVALID_PARAMETER { // the process no longer exists return false, nil } else if err != nil { return false, NewWindowsError("OpenProcess", err) } defer wrappers.CloseHandle(hProcess) // wait with a timeout of 0 to check the process's status and make sure it's not a zombie event, err := wrappers.WaitForSingleObject(hProcess, 0) if err != nil { return false, NewWindowsError("WaitForSingleObject", err) } return event != wrappers.WAIT_OBJECT_0, nil }
func SignalProcessAndWait(pid uint, timeout time.Duration) error { milliseconds := uint32(timeout / time.Millisecond) if timeout < 0 { milliseconds = wrappers.INFINITE } hProcess, err := wrappers.OpenProcess(wrappers.SYNCHRONIZE, false, uint32(pid)) if err == wrappers.ERROR_INVALID_PARAMETER { // the process terminated on its own return nil } else if err != nil { return NewWindowsError("OpenProcess", err) } defer wrappers.CloseHandle(hProcess) if err := wrappers.GenerateConsoleCtrlEvent(wrappers.CTRL_BREAK_EVENT, uint32(pid)); err == wrappers.ERROR_INVALID_PARAMETER { // the process terminated on its own return nil } else if err != nil { return NewWindowsError("GenerateConsoleCtrlEvent", err) } if _, err := wrappers.WaitForSingleObject(hProcess, milliseconds); err != nil { return NewWindowsError("WaitForSingleObject", err) } return nil }