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

如何在AHK中通过DllCall调用CreateProcessW函数?

在AutoHotkey中正确调用CreateProcessW的方法

首先,CreateProcessW是Windows API中参数要求严格的函数,不能仅传递第一个路径参数就调用——哪怕不需要某些功能,也得明确传递对应占位值(比如NULL,对应AHK里的0),否则函数会执行失败。下面一步步解决你的问题:

1. SECURITY_ATTRIBUTES结构体的处理

如果不需要自定义安全属性,直接给lpProcessAttributes和lpThreadAttributes参数传0即可,不用手动构建结构体。如果确实需要配置安全属性,用AHK的NumPut在内存中构建结构体:

; 示例:构建允许子进程继承句柄的SECURITY_ATTRIBUTES
SA_SIZE := A_PtrSize * 3  ; 结构体由dwLength(4字节)、lpSecurityDescriptor(指针)、bInheritHandle(4字节)组成
SA := NumPut(SA_SIZE, Buffer := Allocate(SA_SIZE), 0, "UInt")  ; 设置dwLength为结构体总大小
NumPut(0, Buffer, A_PtrSize, "Ptr")  ; lpSecurityDescriptor设为NULL
NumPut(1, Buffer, A_PtrSize*2, "UInt")  ; bInheritHandle设为1(允许继承)
; 调用时将SA作为Ptr类型参数传递

2. 必须填充STARTUPINFOW结构体

CreateProcessW要求lpStartupInfo参数必须指向有效的STARTUPINFOW结构体,至少要设置cb成员为结构体的大小:

SI_SIZE := A_Is64bitOS ? 104 : 68  ; 64位系统该结构体大小为104字节,32位为68字节
SI := NumPut(SI_SIZE, Buffer := Allocate(SI_SIZE), 0, "UInt")

3. 完整调用示例

以下是能正常启动记事本的完整代码,包含所有必要参数:

; 分配PROCESS_INFORMATION结构体内存,用于接收进程/线程句柄
PI_SIZE := A_PtrSize * 4  ; 结构成员:hProcess(指针)、hThread(指针)、dwProcessId(DWORD)、dwThreadId(DWORD)
PI := Allocate(PI_SIZE)

; 构建STARTUPINFOW结构体
SI_SIZE := A_Is64bitOS ? 104 : 68
SI := NumPut(SI_SIZE, Buffer := Allocate(SI_SIZE), 0, "UInt")

; 调用CreateProcessW
Result := DllCall("CreateProcessW"
    , "WStr", "notepad.exe"       ; lpApplicationName:要启动的程序路径
    , "Ptr", 0                    ; lpCommandLine:用lpApplicationName的话此处传0
    , "Ptr", 0                    ; lpProcessAttributes:NULL,使用默认安全属性
    , "Ptr", 0                    ; lpThreadAttributes:NULL,使用默认安全属性
    , "UInt", 0                   ; bInheritHandles:不继承父进程句柄
    , "UInt", 0                   ; dwCreationFlags:默认创建标志
    , "Ptr", 0                    ; lpEnvironment:继承父进程环境变量
    , "Ptr", 0                    ; lpCurrentDirectory:继承父进程工作目录
    , "Ptr", SI                   ; lpStartupInfo:指向构建好的STARTUPINFOW
    , "Ptr", PI                   ; lpProcessInformation:接收进程信息
    , "UInt")

; 检查调用结果
if (Result = 0) {
    MsgBox, 调用失败!错误码:%A_LastError%
} else {
    ; 关闭不必要的句柄(Windows API要求用完释放)
    DllCall("CloseHandle", "Ptr", NumGet(PI, 0, "Ptr"))  ; 关闭进程句柄
    DllCall("CloseHandle", "Ptr", NumGet(PI, A_PtrSize, "Ptr"))  ; 关闭线程句柄
    MsgBox, 记事本已启动!
}

; 释放分配的内存
Free(SI)
Free(PI)

; 辅助函数:分配内存
Allocate(Size) {
    return DllCall("GlobalAlloc", "UInt", 0x0040, "UInt", Size, "Ptr")
}

; 辅助函数:释放内存
Free(Ptr) {
    DllCall("GlobalFree", "Ptr", Ptr)
}

关键注意点

  • CreateProcessW的参数顺序必须严格匹配官方文档,不能随意省略;
  • 用完PROCESS_INFORMATION中的句柄后,必须调用CloseHandle释放系统资源;
  • 调用失败时,可通过A_LastError获取具体错误码,辅助排查问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 21:37:12