# 进程函数

用于对进程执行下列操作的函数: 检查它是否存在; 改变它的优先级; 关闭它; 等待它的存在; 等待它关闭. 单击函数名查看详细信息.

函数 | 描述
--- | ---
ProcessClose | 强制关闭第一个匹配的进程.
ProcessExist | 检查指定的进程是否存在.
ProcessGetName | 返回指定进程的名称.
ProcessGetParent | 返回创建指定进程的进程 ID(PID).
ProcessGetPath | 返回指定进程的路径.
ProcessSetPriority | 更改第一个匹配进程的优先级.
ProcessWait | 等待指定的进程存在.
ProcessWaitClose | 等待匹配进程关闭.

## 备注

进程列表: 虽然没有 ProcessList 函数, 但示例 #1 和示例 #2 演示了如何通过 DllCall 或 COM 检索进程.

## 相关

Run, WinClose, WinKill, WinWait, WinWaitClose, WinExist, 窗口函数

## 示例

显示一个通过 DllCall 获取的正在运行的进程列表.

    d := "  |  "  ; 字符串分隔符
    s := 4096  ; 缓冲和数组的大小(4 KB)

    ScriptPID := ProcessExist()  ; 正在运行脚本的 PID.
    ; 使用 PROCESS_QUERY_INFORMATION(0x0400) 获取此脚本的句柄:
    h := DllCall("OpenProcess", "UInt", 0x0400, "Int", false, "UInt", ScriptPID, "Ptr")
    ; 打开此进程的可调整的访问令牌(TOKEN_ADJUST_PRIVILEGES = 32):
    DllCall("Advapi32.dll\OpenProcessToken", "Ptr", h, "UInt", 32, "PtrP", &t := 0)
    ; 获取调试特权的本地唯一标识符:
    DllCall("Advapi32.dll\LookupPrivilegeValue", "Ptr", 0, "Str", "SeDebugPrivilege", "Int64P", &luid := 0)
    ti := Buffer(16, 0)  ; 特权结构
    NumPut( "UInt", 1  ; 特权数组中的一个条目...
          , "Int64", luid
          , "UInt", 2  ; 启用这个特权: SE_PRIVILEGE_ENABLED = 2
          , ti)
    ; 使用新的访问令牌更新此进程的特权:
    r := DllCall("Advapi32.dll\AdjustTokenPrivileges", "Ptr", t, "Int", false, "Ptr", ti, "UInt", 0, "Ptr", 0, "Ptr", 0)
    DllCall("CloseHandle", "Ptr", t)  ; 关闭访问令牌句柄以节约内存.
    DllCall("CloseHandle", "Ptr", h)  ; 关闭进程句柄以节约内存.

    hModule := DllCall("LoadLibrary", "Str", "Psapi.dll")  ; 通过预加载来提升性能.
    a := Buffer(s)  ; 接收进程列表标识符的数组:
    c := 0  ; 用于进程标识符的计数器
    l := ""
    DllCall("Psapi.dll\EnumProcesses", "Ptr", a, "UInt", s, "UIntP", &r)
    Loop r // 4  ; 把数组解析为 DWORD(32 位) 的标识符:
    {
        id := NumGet(a, A_Index * 4, "UInt")
        ; 打开进程: PROCESS_VM_READ (0x0010) | PROCESS_QUERY_INFORMATION (0x0400)
        h := DllCall("OpenProcess", "UInt", 0x0010 | 0x0400, "Int", false, "UInt", id, "Ptr")
        if !h
            continue
        n := Buffer(s, 0)  ; 接收模块基础名称的缓冲:
        e := DllCall("Psapi.dll\GetModuleBaseName", "Ptr", h, "Ptr", 0, "Ptr", n, "UInt", s//2)
        if !e    ; 用于 64 位进程在 32 位模式时的回退方法:
            e := DllCall("Psapi.dll\GetProcessImageFileName", "Ptr", h, "Ptr", n, "UInt", s//2)
        SplitPath StrGet(n), &n
        DllCall("CloseHandle", "Ptr", h)  ; 关闭进程句柄以节约内存
        if (n && e)  ; 如果映像不是空的, 则添加到列表:
            l .= n "`n", c++
    }
    DllCall("FreeLibrary", "Ptr", hModule)  ; 卸载库来释放内存.
    ;l := Sort(l)  ; 取消注释这行来按字母顺序对列表进行排序.
    MsgBox StrReplace(l, "`n", d), c " Processes", 0

显示使用 COM 和 Win32_Process 获取的正在运行的进程列表.

    MyGui := Gui(, "Process List")
    LV := MyGui.Add("ListView", "x2 y0 w400 h500", ["Process Name","Command Line"])
    for process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
        LV.Add("", process.Name, process.CommandLine)
    MyGui.Show

dftg