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

使用Rust Windows crate获取PID时GetWindowThreadProcessId报错1400

问题分析与解决

错误码1400表示无效窗口句柄,核心问题出在FindWindowA的调用逻辑上:

  • FindWindowA的第二个参数是窗口标题(窗口文本),并非进程文件名。你传入"ac_client.exe"无法匹配到对应窗口,返回了无效的NULL句柄,后续调用GetWindowThreadProcessId自然触发无效句柄错误。
  • 另外,FindWindowA找不到窗口时仅返回NULL,不一定会设置GetLastError,所以第一个错误码为0不代表调用成功,必须检查返回的窗口句柄是否有效。

解决方法

方法1:已知窗口标题时直接调用

如果知道ac_client.exe对应的窗口标题,直接替换第二个参数即可:

fn main(){
    unsafe{
        // 替换为ac_client.exe实际的窗口标题
        let window_title: PCSTR = windows::s!("AssaultCube");         
        let window = windows::Win32::UI::WindowsAndMessaging::FindWindowA(None, window_title);

        if window.is_invalid() {
            println!("找不到目标窗口");
            return;
        }

        let mut pId = 0;
        windows::Win32::UI::WindowsAndMessaging::GetWindowThreadProcessId(window, Some(&mut pId));
        
        let error = windows::Win32::Foundation::GetLastError();
        if error.is_ok() {
            println!("目标PID: {}", pId);
        } else {
            println!("获取PID失败: {:?}", error);
        }
    }
}

方法2:通过进程名匹配(遍历所有窗口)

如果不知道窗口标题,需要遍历系统中所有窗口,逐一验证所属进程的名称:

use windows::Win32::{
    Foundation::{HWND, BOOL, LPARAM},
    UI::WindowsAndMessaging::{EnumWindows, GetWindowThreadProcessId},
    System::Threading::{OpenProcess, PROCESS_QUERY_INFORMATION, PROCESS_VM_READ},
    System::Diagnostics::ToolHelp::GetModuleFileNameExA,
};

unsafe extern "system" fn enum_windows_proc(window: HWND, param: LPARAM) -> BOOL {
    let target_pid = param.0 as *mut u32;
    
    let mut pid = 0;
    GetWindowThreadProcessId(window, Some(&mut pid));

    if pid == 0 {
        return BOOL(1);
    }

    let process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, pid);
    if process.is_invalid() {
        return BOOL(1);
    }

    let mut buffer = [0u8; 256];
    let len = GetModuleFileNameExA(process, None, &mut buffer);
    if len > 0 {
        let process_name = String::from_utf8_lossy(&buffer[..len as usize]);
        if process_name.contains("ac_client.exe") {
            *target_pid = pid;
            return BOOL(0); // 找到目标,停止遍历
        }
    }

    BOOL(1) // 继续遍历
}

fn main(){
    unsafe{
        let mut target_pid = 0;
        EnumWindows(Some(enum_windows_proc), LPARAM(&mut target_pid as *mut u32 as isize));

        if target_pid != 0 {
            println!("目标PID: {}", target_pid);
        } else {
            println!("未找到目标进程");
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 09:45:33