ctypes CreateProcessWithLogonW执行后Python进程失败

2024-10-01 22:32:51 发布

您现在位置:Python中文网/ 问答频道 /正文

我尝试在另一个用户下执行python脚本(通过python进程)。我在网上找到了这段代码的一部分,运行得很好;除了一件事。在

当进程终止时,python将失败。在

所以说清楚,不同用户下的第二个python进程使用CreateProcessWithLogonW执行得很好,但是第一个脚本失败了(我想)。在

我的想法可能是错误的,我的代码使用可能是错误的。。。在

一个python进程会导致什么反应迟钝?在

我试过很多东西(例如系统出口(0)以明确任务已完成…,但无法获取。在

我在win7上运行python2.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()

谢谢你的任何启示(:


Tags: innoneifinformationnotctypesnullhandle
2条回答

句柄是64位系统上的64位整数类型。尝试“从”ctypes.wintypes“导入句柄”而不是“句柄=DWORD”

检查lpApplicationNamelpCommandLine的参数;解决方法之一是为前者传递NULL,为后者传递完整的命令行:

p = CreateProcessWithLogonW('user',
                            'domain',
                            'password',
                            0,
                            NULL,
                            r'C:\Python26\python.exe C:\mySimpleScript.py')

有关详细信息,请参阅CreateProcessWithLogonW的文档。在

相关问题 更多 >

    热门问题