使用Rust调用Windows API获取PID时进程名异常问题
问题分析与修复
你的代码存在两个核心问题,导致进程名显示异常且无法正确匹配目标进程:
- 字符串比较顺序完全颠倒:每次循环先创建空的
proc_exe_string就直接和目标进程名比较,永远无法匹配,导致遍历所有进程;同时PROCESSENTRY32的szExeFile是固定大小缓冲区,未被清零的残留字符会被追加到新的进程名后,出现重复后缀。 - 错误遍历整个
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
相关产品推荐
相关产品推荐

