You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

修复ctypes调用CreateProcessWithTokenW时参数1转换错误问题

调用CreateProcessWithTokenW报错的问题修复

问题代码

import ctypes
import win32security

h_token = win32security.OpenProcessToken(ctypes.windll.kernel32.GetCurrentProcess(), win32security.TOKEN_ALL_ACCESS)

lpApplicationName = ctypes.c_wchar_p(rf"C:\Windows\System32\cmd.exe")
lpCommandLine = ctypes.c_wchar_p("")
dwCreationFlags = 0x00000010
lpEnvironment = None
lpProcessAttributes = None
lpThreadAttributes = None
bInheritHandles = False

ctypes.windll.advapi32.CreateProcessWithTokenW(h_token, 0, lpApplicationName, lpCommandLine, dwCreationFlags, lpEnvironment, None, lpProcessAttributes, lpThreadAttributes, bInheritHandles)

报错信息

Traceback (most recent call last):
  File "testx.py", line 96, in <module>
    ctypes.windll.advapi32.CreateProcessWithTokenW(h_token, 0, lpApplicationName, lpCommandLine, dwCreationFlags, lpEnvironment, None, lpProcessAttributes, lpThreadAttributes, bInheritHandles)
ctypes.ArgumentError: argument 1: TypeError: Don't know how to convert parameter 1

错误原因与修复方案

1. 令牌句柄类型不匹配

win32security.OpenProcessToken返回的是PyHANDLE对象,而ctypes无法直接将该类型转换为Windows API所需的原生HANDLE(整数类型)。

修复方法:提取PyHANDLE的.handle属性,获取原生整数句柄:

native_token = h_token.handle

2. API参数顺序与结构体缺失

代码混淆了CreateProcessWithTokenW和CreateProcessW的参数列表,前者不需要lpProcessAttributes、lpThreadAttributes、bInheritHandles,而是要求最后两个参数为STARTUPINFO和PROCESS_INFORMATION结构体的指针。

修复后的完整代码:

import ctypes
import win32security
from ctypes import wintypes

# 定义Windows API所需的结构体
class STARTUPINFO(ctypes.Structure):
    _fields_ = [
        ("cb", wintypes.DWORD),
        ("lpReserved", wintypes.LPWSTR),
        ("lpDesktop", wintypes.LPWSTR),
        ("lpTitle", wintypes.LPWSTR),
        ("dwX", wintypes.DWORD),
        ("dwY", wintypes.DWORD),
        ("dwXSize", wintypes.DWORD),
        ("dwYSize", wintypes.DWORD),
        ("dwXCountChars", wintypes.DWORD),
        ("dwYCountChars", wintypes.DWORD),
        ("dwFillAttribute", wintypes.DWORD),
        ("dwFlags", wintypes.DWORD),
        ("wShowWindow", wintypes.WORD),
        ("cbReserved2", wintypes.WORD),
        ("lpReserved2", wintypes.LPBYTE),
        ("hStdInput", wintypes.HANDLE),
        ("hStdOutput", wintypes.HANDLE),
        ("hStdError", wintypes.HANDLE),
    ]

class PROCESS_INFORMATION(ctypes.Structure):
    _fields_ = [
        ("hProcess", wintypes.HANDLE),
        ("hThread", wintypes.HANDLE),
        ("dwProcessId", wintypes.DWORD),
        ("dwThreadId", wintypes.DWORD),
    ]

# 获取当前进程令牌并转换为原生句柄
h_process = ctypes.windll.kernel32.GetCurrentProcess()
h_token = win32security.OpenProcessToken(h_process, win32security.TOKEN_ALL_ACCESS)
native_token = h_token.handle

# 初始化结构体
si = STARTUPINFO()
si.cb = ctypes.sizeof(STARTUPINFO)
pi = PROCESS_INFORMATION()

# 调用CreateProcessWithTokenW
result = ctypes.windll.advapi32.CreateProcessWithTokenW(
    native_token,
    0,  # LOGON_WITH_PROFILE
    ctypes.c_wchar_p(r"C:\Windows\System32\cmd.exe"),
    ctypes.c_wchar_p(""),
    0x00000010,  # CREATE_NEW_CONSOLE
    None,
    None,
    ctypes.byref(si),
    ctypes.byref(pi)
)

# 检查调用是否成功
if not result:
    raise ctypes.WinError(ctypes.get_last_error())

# 关闭句柄释放资源
ctypes.windll.kernel32.CloseHandle(pi.hProcess)
ctypes.windll.kernel32.CloseHandle(pi.hThread)

额外注意事项

  • 调用Windows API后要检查返回值,通过ctypes.get_last_error()获取具体错误码,便于排查问题。
  • 进程和线程句柄使用完毕后必须关闭,避免系统资源泄漏。
  • CreateProcessWithTokenW需要调用进程拥有SE_IMPERSONATE_NAME权限,否则会调用失败。

内容的提问来源于stack exchange,提问作者zzzzzzd

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.01 17:40:25