我正在尝试使用ctypes重新创建psutil项目(https://code.google.com/p/psutil/)上的一些功能。使用psutil对我想要的东西来说太过分了,这只是检查一个给定的pid当前是否正在运行。
我正在尝试重新创建的代码段是pid_is_running function。
int
pid_is_running(DWORD pid)
{
HANDLE hProcess;
DWORD exitCode;
// Special case for PID 0 System Idle Process
if (pid == 0) {
return 1;
}
if (pid < 0) {
return 0;
}
hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
FALSE, pid);
if (NULL == hProcess) {
// invalid parameter is no such process
if (GetLastError() == ERROR_INVALID_PARAMETER) {
CloseHandle(hProcess);
return 0;
}
// access denied obviously means there's a process to deny access to...
if (GetLastError() == ERROR_ACCESS_DENIED) {
CloseHandle(hProcess);
return 1;
}
CloseHandle(hProcess);
PyErr_SetFromWindowsErr(0);
return -1;
}
if (GetExitCodeProcess(hProcess, &exitCode)) {
CloseHandle(hProcess);
return (exitCode == STILL_ACTIVE);
}
// access denied means there's a process there so we'll assume it's running
if (GetLastError() == ERROR_ACCESS_DENIED) {
CloseHandle(hProcess);
return 1;
}
PyErr_SetFromWindowsErr(0);
CloseHandle(hProcess);
return -1;
}
我不明白为什么代码正在关闭一个NULL句柄。这真的有必要吗?是错还是可能导致错误?
我也很感激到目前为止我能提出的任何意见
import os
import shlex
import subprocess
import ctypes as c
import ctypes.wintypes as w
PROCESS_QUERY_INFORMATION = 0x0400L
PROCESS_VM_READ = 0x0010L
ERROR_INVALID_PARAMETER = 0x57L
ERROR_ACCESS_DENIED = 0x5L
STILL_ACTIVE = 0x103L
FALSE = 0L
def start(cmd):
l = shlex.split(cmd)
return subprocess.Popen(l).pid
def get_pid(hProcess):
pid = w.DWORD()
return c.windll.kernel32.GetProcessId(hProcess);
def pid_is_running(pid):
# adapted from psutil library
# http://code.google.com/searchframe#Dnjw9wRLlM4/trunk/psutil/arch/mswindows/process_info.c&q=pid_is_running%20package:psutil\.googlecode\.com&l=150
pid = w.DWORD(pid)
hProcess = w.HANDLE()
if pid.value == 0L:
return True
if pid.value < 0L:
return False
flags = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ
hProcess = c.windll.kernel32.OpenProcess(flags, FALSE, pid)
try:
if 0 == hProcess:
# invalid parameter is no such process
last_error = c.windll.kernel32.GetLastError()
if last_error == ERROR_INVALID_PARAMETER:
return False
# access denied obviously means there's a process to deny access to...
if last_error == ERROR_ACCESS_DENIED:
return True
#return -1 # Error? Should I throw an exception
raise Exception('Could not find process and an error occurred')
else:
exitCode = w.DWORD()
if c.windll.kernel32.GetExitCodeProcess(hProcess, c.byref(exitCode)):
return exitCode.value == STILL_ACTIVE
# access denied means there's a process there so we'll assume it's running
if c.windll.kernel32.GetLastError() == ERROR_ACCESS_DENIED:
return True
#return -1 # Error? Should I throw an exception
raise Exception('Process found and an error occurred')
finally:
if hProcess != 0:
c.windll.kernel32.CloseHandle(hProcess)
答案 0 :(得分:1)
可能会自动生成每个返回路径关闭它。即使是C程序员也没有足够的愚蠢来在每条路径上释放资源,他们使用的是基于goto的清理习惯。
当然,
针对未在API中公开的ntdll函数进行编译
可能表示该代码使用内部NT API函数,这些函数必将在以后的任何时候更改并破坏lolsies的代码。