我正在尝试在另一个用户下执行python脚本(通过python进程)。我在网上找到了部分代码并且效果很好;除了一件事。
当进程终止时,python失败。
所以要明确的是,不同用户下的第二个python进程在CreateProcessWithLogonW下运行良好,但是第一个脚本失败了(我认为)。
我的想法可能是错的,我的代码使用可能是错误的......
知道什么可能导致一个python进程无响应吗?
我已经尝试了很多东西(比如在两个脚本中放置sys.exit(0)以明确任务已完成...),但无法获得它。
我在win7上运行python 2.6 64bit
import ctypes
import win32api
import win32event
import win32process
NULL = 0
TRUE = 1
FALSE = 0
INVALID_HANDLE_VALUE = -1
CREATE_DEFAULT_ERROR_MODE = 0x04000000
DETACHED_PROCESS = 0x00000008
WORD = ctypes.c_ushort
DWORD = ctypes.c_uint
LPSTR = ctypes.c_char_p
LPBYTE = LPSTR
HANDLE = DWORD
# typedef struct _PROCESS_INFORMATION {
# HANDLE hProcess;
# HANDLE hThread;
# DWORD dwProcessId;
# DWORD dwThreadId;
# } PROCESS_INFORMATION, *PPROCESS_INFORMATION, *LPPROCESS_INFORMATION;
class PROCESS_INFORMATION(ctypes.Structure):
_pack_ = 1
_fields_ = [
('hProcess', HANDLE),
('hThread', HANDLE),
('dwProcessId', DWORD),
('dwThreadId', DWORD),
]
# typedef struct _STARTUPINFO {
# DWORD cb;
# LPSTR lpReserved;
# LPSTR lpDesktop;
# LPSTR lpTitle;
# DWORD dwX;
# DWORD dwY;
# DWORD dwXSize;
# DWORD dwYSize;
# DWORD dwXCountChars;
# DWORD dwYCountChars;
# DWORD dwFillAttribute;
# DWORD dwFlags;
# WORD wShowWindow;
# WORD cbReserved2;
# LPBYTE lpReserved2;
# HANDLE hStdInput;
# HANDLE hStdOutput;
# HANDLE hStdError;
# } STARTUPINFO, *LPSTARTUPINFO;
class STARTUPINFO(ctypes.Structure):
_pack_ = 1
_fields_ = [
('cb', DWORD),
('lpReserved', DWORD), # LPSTR
('lpDesktop', LPSTR),
('lpTitle', LPSTR),
('dwX', DWORD),
('dwY', DWORD),
('dwXSize', DWORD),
('dwYSize', DWORD),
('dwXCountChars', DWORD),
('dwYCountChars', DWORD),
('dwFillAttribute', DWORD),
('dwFlags', DWORD),
('wShowWindow', WORD),
('cbReserved2', WORD),
('lpReserved2', DWORD), # LPBYTE
('hStdInput', DWORD),
('hStdOutput', DWORD),
('hStdError', DWORD),
]
# BOOL WINAPI CreateProcessWithLogonW(
# __in LPCWSTR lpUsername,
# __in_opt LPCWSTR lpDomain,
# __in LPCWSTR lpPassword,
# __in DWORD dwLogonFlags,
# __in_opt LPCWSTR lpApplicationName,
# __inout_opt LPWSTR lpCommandLine,
# __in DWORD dwCreationFlags,
# __in_opt LPVOID lpEnvironment,
# __in_opt LPCWSTR lpCurrentDirectory,
# __in LPSTARTUPINFOW lpStartupInfo,
# __out LPPROCESS_INFORMATION lpProcessInfo
# );
def CreateProcessWithLogonW(lpUsername=None, lpDomain=None, lpPassword=None,
dwLogonFlags=0, lpApplicationName=None, lpCommandLine=None,
dwCreationFlags=0, lpEnvironment=None, lpCurrentDirectory=None,
lpStartupInfo = None):
if not lpUsername:
lpUsername = NULL
else:
lpUsername = ctypes.c_wchar_p(lpUsername)
if not lpDomain:
lpDomain = NULL
else:
lpDomain = ctypes.c_wchar_p(lpDomain)
if not lpPassword:
lpPassword = NULL
else:
lpPassword = ctypes.c_wchar_p(lpPassword)
if not lpApplicationName:
lpApplicationName = NULL
else:
lpApplicationName = ctypes.c_wchar_p(lpApplicationName)
if not lpCommandLine:
lpCommandLine = NULL
else:
lpCommandLine = ctypes.create_unicode_buffer(lpCommandLine)
if not lpEnvironment:
lpEnvironment = NULL
else:
lpEnvironment = ctypes.c_wchar_p(lpEnvironment)
if not lpCurrentDirectory:
lpCurrentDirectory = NULL
else:
lpCurrentDirectory = ctypes.c_wchar_p(lpCurrentDirectory)
if not lpStartupInfo:
lpStartupInfo = STARTUPINFO()
lpStartupInfo.cb = ctypes.sizeof(STARTUPINFO)
lpStartupInfo.lpReserved = 0
lpStartupInfo.lpDesktop = 0
lpStartupInfo.lpTitle = 0
lpStartupInfo.dwFlags = 0
lpStartupInfo.cbReserved2 = 0
lpStartupInfo.lpReserved2 = 0
lpStartupInfo.hStdInput = win32api.GetStdHandle(win32api.STD_INPUT_HANDLE)
lpStartupInfo.hStdOutput = win32api.GetStdHandle(win32api.STD_OUTPUT_HANDLE)
lpStartupInfo.hStdError = win32api.GetStdHandle(win32api.STD_ERROR_HANDLE)
lpProcessInformation = PROCESS_INFORMATION()
lpProcessInformation.hProcess = INVALID_HANDLE_VALUE
lpProcessInformation.hThread = INVALID_HANDLE_VALUE
lpProcessInformation.dwProcessId = 0
lpProcessInformation.dwThreadId = 0
dwCreationFlags |= win32process.CREATE_NEW_CONSOLE
success = ctypes.windll.advapi32.CreateProcessWithLogonW(lpUsername,
lpDomain,
lpPassword,
dwLogonFlags,
lpApplicationName,
ctypes.byref(lpCommandLine),
dwCreationFlags,
lpEnvironment,
lpCurrentDirectory,
ctypes.byref(lpStartupInfo),
ctypes.byref(lpProcessInformation))
if success == FALSE:
raise ctypes.WinError()
win32event.WaitForSingleObject(lpProcessInformation.hProcess, win32event.INFINITE)
ctypes.windll.kernel32.CloseHandle(lpProcessInformation.hProcess)
ctypes.windll.kernel32.CloseHandle(lpProcessInformation.hThread)
return lpProcessInformation
def test():
p = CreateProcessWithLogonW('user',
'domain',
'password',
0,
r'C:\Python26\python.exe',
r'C:\Python26\python.exe C:\mySimpleScript.py')
if __name__ == '__main__':
test()
感谢任何启发(:
答案 0 :(得分:1)
检查 lpApplicationName 和 lpCommandLine 的参数;修复它的一种方法是为前者传递NULL,为后者传递完整的命令行:
p = CreateProcessWithLogonW('user',
'domain',
'password',
0,
NULL,
r'C:\Python26\python.exe C:\mySimpleScript.py')
有关详细信息,请参阅CreateProcessWithLogonW的文档。
答案 1 :(得分:1)
HANDLE是64位系统上的64位整数类型。尝试“从ctypes.wintypes导入HANDLE”而不是“HANDLE = DWORD”