# Process

对一个进程执行下面的其中一个操作: 检查是否存在; 改变优先级; 关闭; 等待关闭.

Process, Cmd, PID-or-Name [, Param3]

#### 参数

Cmd | 下列单词的其中一个: Exist: 如果一个匹配的进程存在则设置 ErrorLevel 为该进程 ID (PID) , 否则设置为 0. 如果 PID-or-Name 参数为空, 将获取脚本自己的 PID . 获取脚本自己的 PID 的一个单行方法是 PID := DllCall("GetCurrentProcessId") Close: 如果成功终止一个匹配的进程, ErrorLevel 被设置为该进程原来的进程 ID (PID). 否则(没有找到匹配的进程或者在终止匹配进程的过程中出现了问题),它被设置为0.当一个进程被意外终止时 -- 可能在一个致命点中断它的工作或者导致窗口中没有保存数据的丢失 (如果有的话) -- 只有当无法使用 WinClose 命令作用于它的窗口上来关闭相应进程时才应该使用这种方法. List: 尽管 List 还不支持, 示例段 中的例子演示了通过 DllCall获取进程列表的方法. Priority: 改变首个匹配进程的优先级为 Param3 (如同任务管理器中看到的那样)同时设置 ErrorLevel 为该进程 ID (PID). 如果 PID-or-Name 参数为空, 将改变脚本自己的优先级. 没有找到匹配的进程或者在改变匹配进程的优先级过程中出现了问题, ErrorLevel 将被设置为0. Param3 应该为下列字母或单词的其中一个: L (或 Low), B (或 BelowNormal), N (或 Normal), A (或 AboveNormal), H (或 High), R (或 Realtime). 因为在 Windows 95/98/Me/NT4中, BelowNormal 和 AboveNormal 不被支持, 所以在这些系统中将自动使用 normal 代替它们. 注意: 任何不是设计为实时运行的进程如果设置为实时的优先级可能降低系统的稳定性. Wait: 在 Param3 指定的秒数 (可以包含小数点) 中检查一个匹配的进程是否存在. 如果 Param3 省略, 命令将无限期等待. 如果找到一个匹配的进程, ErrorLevel 被设置为该进程的进程 ID (PID). 如果命令超时, ErrorLevel 被设置为 0 . WaitClose: 在 Param3 指定的秒数 (可以包含小数点) 中检查所有匹配的进程是否关闭.如果 Param3 省略, 命令将等待不确定的时间.如果所有的匹配进程都关闭了, ErrorLevel 将被设置为 0. 如果命令超时, ErrorLevel 被设置为仍然存在的第一个匹配进程的进程 ID (PID) .
PID-or-Name | 该参数可以是一个数字 (PID) 或者如同下面描述的进程名. 它可以留空来改变脚本自己的优先级. PID: 进程 ID, 唯一标识一个特定进程的数字 (只有在该进程的生存期这个数字才是有效的). 新运行的进程的 PID 可以通过 Run 命令获取. 同样的, 一个窗口的 PID 可以通过 WinGet 命令获取. Process 命令自身也可以用来获取 PID. Name: 一个进程的名称通常和它的可执行文件名称相同 (不含路径), 例如 notepad.exe 或 winword.exe. 因为一个名称可能匹配多个正在运行的进程, 只会对第一个进程进行操作. 名称的大小写不敏感.
Param3 | 查看上面的 Cmd 获取细节.

#### ErrorLevel

查看上面的 Cmd 获取细节.

#### 备注

对于 Wait 和 WaitClose: 每隔 100 毫秒检查目标进程一次; 目标进程满足条件时, 命令不再继续等待. 换句话说, 这时不会等待超时时间到期, 而是立即像上面描述的那样设置 ErrorLevel, 然后继续往后执行脚本. 此外, 当该命令处于等待状态时, 新的 线程 可以通过 热键, 自定义菜单项, 或 计时器 启动.

在 Windows NT4 系统上, Process 命令需要 PSAPI.DLL文件, 通常该文件存在于 AutoHotkey 的安装目录 (即不需要为 NT 系统进行额外的安装步骤). 然而, 在 Windows NT4 中执行含有该命令的 已编译脚本 时, 需要在脚本所在目录或系统的 PATH 变量的路径中包含一个 PSAPI.DLL 文件的副本 (尽管某些 NT4 系统可能含有该 DLL 文件).

#### 相关

Run, WinGet, WinClose, WinKill, WinWait, WinWaitClose, IfWinExist

#### 示例

    ; Example #1:
    Run Notepad.exe, , , NewPID
    Process, priority, %NewPID%, High
    MsgBox The newly launched notepad's PID is %NewPID%.

?

    ; Example #2:

    Process, wait, Notepad.exe, 5.5
    NewPID = %ErrorLevel%  ; Save the value immediately since ErrorLevel is often changed.
    if NewPID = 0
    {
        MsgBox The specified process did not appear within 5.5 seconds.
        Return
    }
    ; Otherwise:
    MsgBox A matching process has appeared (Process ID is %NewPID%).
    Process, priority, %NewPID%, Low
    Process, priority, , High  ; Have the script set itself to high priority.
    WinClose Untitled - Notepad
    Process, WaitClose, %NewPID%, 5
    if ErrorLevel ; The PID still exists.
        MsgBox The process did not close within 5 seconds.

?

    ; Example #3: A hotkey to change the priority of the active window's process:

    #z:: ; Win+Z hotkey
    WinGet, active_pid, PID, A
    WinGetTitle, active_title, A
    Gui, 5:Add, Text,, Press ESCAPE to cancel, or double-click a new`npriority level for the following window:`n%active_title%
    Gui, 5:Add, ListBox, vMyListBox gMyListBox r5, Normal|High|Low|BelowNormal|AboveNormal
    Gui, 5:Add, Button, default, OK
    Gui, 5:Show,, Set Priority
    return

    5GuiEscape:
    5GuiClose:
    Gui, Destroy
    return

    MyListBox:
    if A_GuiEvent <> DoubleClick
        return
    ; else fall through to the next label:
    5ButtonOK:
    GuiControlGet, MyListBox
    Gui, Destroy
    Process, Priority, %active_pid%, %MyListBox%
    if ErrorLevel
        MsgBox Success: Its priority was changed to "%MyListBox%".
    else
        MsgBox Error: Its priority could not be changed to "%MyListBox%".
    return

?

    ; Example #4: Retrieves a list of running processes via DllCall then shows them in a MsgBox.

    d = `n  ; string separator
    s := 4096  ; size of buffers and arrays (4 KB)

    Process, Exist  ; sets ErrorLevel to the PID of this running script
    ; Get the handle of this script with PROCESS_QUERY_INFORMATION (0x0400)
    h := DllCall("OpenProcess", "UInt", 0x0400, "Int", false, "UInt", ErrorLevel)
    ; Open an adjustable access token with this process (TOKEN_ADJUST_PRIVILEGES = 32)
    DllCall("Advapi32.dll\OpenProcessToken", "UInt", h, "UInt", 32, "UIntP", t)
    VarSetCapacity(ti, 16, 0)  ; structure of privileges
    NumPut(1, ti, 0)  ; one entry in the privileges array...
    ; Retrieves the locally unique identifier of the debug privilege:
    DllCall("Advapi32.dll\LookupPrivilegeValueA", "UInt", 0, "Str", "SeDebugPrivilege", "Int64P", luid)
    NumPut(luid, ti, 4, "int64")
    NumPut(2, ti, 12)  ; enable this privilege: SE_PRIVILEGE_ENABLED = 2
    ; Update the privileges of this process with the new access token:
    DllCall("Advapi32.dll\AdjustTokenPrivileges", "UInt", t, "Int", false, "UInt", &ti, "UInt", 0, "UInt", 0, "UInt", 0)
    DllCall("CloseHandle", "UInt", h)  ; close this process handle to save memory

    hModule := DllCall("LoadLibrary", "Str", "Psapi.dll")  ; increase performance by preloading the libaray
    s := VarSetCapacity(a, s)  ; an array that receives the list of process identifiers:
    c := 0  ; counter for process idendifiers
    DllCall("Psapi.dll\EnumProcesses", "UInt", &a, "UInt", s, "UIntP", r)
    Loop, % r // 4  ; parse array for identifiers as DWORDs (32 bits):
    {
       id := NumGet(a, A_Index * 4)
       ; Open process with: PROCESS_VM_READ (0x0010) | PROCESS_QUERY_INFORMATION (0x0400)
       h := DllCall("OpenProcess", "UInt", 0x0010 | 0x0400, "Int", false, "UInt", id)
       VarSetCapacity(n, s, 0)  ; a buffer that receives the base name of the module:
       e := DllCall("Psapi.dll\GetModuleBaseNameA", "UInt", h, "UInt", 0, "Str", n, "UInt", s)
       DllCall("CloseHandle", "UInt", h)  ; close process handle to save memory
       if (n && e)  ; if image is not null add to list:
          l .= n . d, c++
    }
    DllCall("FreeLibrary", "UInt", hModule)  ; unload the library to free memory
    ;Sort, l, C  ; uncomment this line to sort the list alphabetically
    MsgBox, 0, %c% Processes, %l%