Files
myclaude/codeagent-wrapper/process_check_windows.go
swe-agent[bot] d7c514e869 Merge branch 'master' into rc/5.2
解决合并冲突:
- .github/workflows/release.yml: 统一使用codeagent-wrapper目录和输出名称
- codeagent-wrapper/main_test.go: 合并HEAD的新测试(Claude/Gemini事件解析)和master的测试改进
- 接受master的新文件: .gitignore, process_check_* 到codeagent-wrapper目录
- 确认删除: codex-wrapper/main.go (已重命名)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-09 16:03:44 +08:00

88 lines
2.0 KiB
Go

//go:build windows
// +build windows
package main
import (
"errors"
"os"
"syscall"
"time"
"unsafe"
)
const (
processQueryLimitedInformation = 0x1000
stillActive = 259 // STILL_ACTIVE exit code
)
var (
findProcess = os.FindProcess
kernel32 = syscall.NewLazyDLL("kernel32.dll")
getProcessTimes = kernel32.NewProc("GetProcessTimes")
fileTimeToUnixFn = fileTimeToUnix
)
// isProcessRunning returns true if a process with the given pid is running on Windows.
func isProcessRunning(pid int) bool {
if pid <= 0 {
return false
}
if _, err := findProcess(pid); err != nil {
return false
}
handle, err := syscall.OpenProcess(processQueryLimitedInformation, false, uint32(pid))
if err != nil {
if errors.Is(err, syscall.ERROR_ACCESS_DENIED) {
return true
}
return false
}
defer syscall.CloseHandle(handle)
var exitCode uint32
if err := syscall.GetExitCodeProcess(handle, &exitCode); err != nil {
return true
}
return exitCode == stillActive
}
// getProcessStartTime returns the start time of a process on Windows.
// Returns zero time if the start time cannot be determined.
func getProcessStartTime(pid int) time.Time {
if pid <= 0 {
return time.Time{}
}
handle, err := syscall.OpenProcess(processQueryLimitedInformation, false, uint32(pid))
if err != nil {
return time.Time{}
}
defer syscall.CloseHandle(handle)
var creationTime, exitTime, kernelTime, userTime syscall.Filetime
ret, _, _ := getProcessTimes.Call(
uintptr(handle),
uintptr(unsafe.Pointer(&creationTime)),
uintptr(unsafe.Pointer(&exitTime)),
uintptr(unsafe.Pointer(&kernelTime)),
uintptr(unsafe.Pointer(&userTime)),
)
if ret == 0 {
return time.Time{}
}
return fileTimeToUnixFn(creationTime)
}
// fileTimeToUnix converts Windows FILETIME to Unix time.
func fileTimeToUnix(ft syscall.Filetime) time.Time {
// FILETIME is 100-nanosecond intervals since January 1, 1601 UTC
nsec := ft.Nanoseconds()
return time.Unix(0, nsec)
}