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

使用Rust调用Windows API获取PID时进程名异常问题

问题分析与修复

你的代码存在两个核心问题,导致进程名显示异常且无法正确匹配目标进程:

  1. 字符串比较顺序完全颠倒:每次循环先创建空的proc_exe_string就直接和目标进程名比较,永远无法匹配,导致遍历所有进程;同时PROCESSENTRY32的szExeFile是固定大小缓冲区,未被清零的残留字符会被追加到新的进程名后,出现重复后缀。
  2. 错误遍历整个szExeFile数组:szExeFile以null字符结尾,直接遍历整个数组会把缓冲区中之前残留的非0字符也加入字符串,导致进程名混乱。

修复后的代码

use windows::Win32::{
    System::Diagnostics::ToolHelp::{CreateToolhelp32Snapshot, Process32First, Process32Next, PROCESSENTRY32, TH32CS_SNAPPROCESS},
    Foundation::{CloseHandle, BOOL, HANDLE},
};

pub unsafe fn get_proc_id(proc_name: &str) -> u32 {
    let mut proc_id: u32 = 0;
    
    // 创建进程快照
    let h_snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
        .expect("Failed to create process snapshot");

    let mut proc_entry = PROCESSENTRY32::default();
    proc_entry.dwSize = std::mem::size_of::<PROCESSENTRY32>() as u32;

    // 获取第一个进程信息
    if Process32First(h_snap, &mut proc_entry).as_bool() {
        loop {
            // 从szExeFile中提取有效字符串(直到第一个null字符)
            let proc_exe_string: String = proc_entry.szExeFile
                .iter()
                .take_while(|&&c| c.0 != 0)
                .map(|c| c.0 as char)
                .collect();

            // 匹配目标进程名
            if proc_exe_string.eq(proc_name) {
                proc_id = proc_entry.th32ProcessID;
                break;
            }

            // 尝试获取下一个进程
            if !Process32Next(h_snap, &mut proc_entry).as_bool() {
                break;
            }
        }
    }

    CloseHandle(h_snap).ok();
    proc_id
}

关键修复点

  • 调整比较逻辑:先提取当前进程的名字符串,再与目标名称匹配,确保能正确找到对应PID。
  • 正确处理szExeFile:使用take_while只遍历到第一个null字符,避免缓冲区残留字符干扰。
  • 优化参数类型:将proc_name改为&str,避免不必要的String拷贝。
  • 修复拼写错误:修正panic中的拼写错误,并改用expect更规范。
  • 完善导入:显式导入所需的Windows API类型和函数,避免隐式调用问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 06:40:51