我想在另一個用戶下執行一個python腳本(通過python進程)。我在網絡上發現了部分代碼,並且工作得很好;除了一件事。ctypes後Python進程失敗CreateProcessWithLogonW執行
當進程終止時,python失敗。
因此要清楚,不同用戶下的第二個python進程與CreateProcessWithLogonW執行得很好,但第一個腳本失敗(我認爲)。
我可能是錯在我的思想,我的代碼使用的可能是錯的...
任何想法可能會導致一個Python進程變得反應遲鈍?
我已經嘗試了很多東西(即像在兩個腳本中放置sys.exit(0)以清楚說明任務已完成...),但無法獲取它。
我Win7上運行與Python 2.6 64位
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()
感謝任何啓示(:
這就是它,非常感謝! – Xavier 2011-01-14 04:26:46