2011-01-14 27 views
1

別のユーザーの下で(pythonプロセスを介して)pythonスクリプトを実行しようとしています。私はこのコードの一部をWeb上で見つけ出し、かなりうまく動作します。一つのことを除いて。ctypes CreateProcessWithLogonW実行後にPythonプロセスが失敗する

プロセスが終了すると、pythonは失敗します。

明らかに、別のユーザーの下の2番目のpythonプロセスはCreateProcessWithLogonWでうまく実行されますが、最初のスクリプトは失敗します(私は思っています)。

1つのpythonのプロセスが応答しなくなる原因となるものをすべてのアイデア私は、私の考えで間違っているかもしれない、と私のコードの使用率が間違っているかもしれない...

私は、タスクが完了したことを明確にするために、両方のスクリプトにsys.exit(0)を置くなど、多くのことを試みましたが、それを取得できませんでした。

私は啓蒙してくれてありがとう(の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() 

とwin7の上で実行しているよ:

答えて

1

HANDLEは64ビットシステム上の64ビット整数型です。 "HANDLE = DWORD"の代わりに "ctypes.wintypes import HANDLE"から試してください

+0

これは本当にありがとうございました! – Xavier

1

lpApplicationNamelpCommandLineのためのあなたの引数を確認してください。それを修正するための1つの方法はにあります前者はNULL、後者は完全なコマンドラインを渡します。

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

詳細については、CreateProcessWithLogonWのドキュメントを参照してください。

関連する問題