Rust调用WinAPI枚举进程时如何将szExeFile转为Unicode字符串
解决方案
核心原理
PROCESSENTRY32 结构体中的 szExeFile 是Windows原生的宽字符(WCHAR,对应Rust的u16类型)数组,以空字符\0作为结束标志,不能直接通过println!打印数组内容。你需要先截取到空字符前的有效内容,再转换为Rust的字符串类型。
实现步骤
- 首先引入Windows字符串转换所需的依赖:
use std::ffi::OsString; use std::os::windows::ffi::OsStringExt;
- 建议优先使用Unicode版本的WinAPI,确保编码正确,需要把原来的API调用替换为带
W后缀的版本:
Process32First替换为Process32FirstWProcess32Next替换为Process32NextWPROCESSENTRY32替换为PROCESSENTRY32W
- 在遍历进程的循环中,添加字符串转换逻辑,替换原来的打印代码:
while Process32NextW(h_process_snap, &mut pe32) != 0 { // 截取第一个空字符之前的有效宽字符切片 let exe_name_slice = pe32.szExeFile.split(|&c| c == 0).next().unwrap_or_default(); // 宽字符切片转OsString,再转换为可打印的字符串 let exe_name = OsString::from_wide(exe_name_slice).to_string_lossy(); println!("{}", exe_name); }
完整修正后的参考代码
use winapi::um::tlhelp32::{Process32NextW, Process32FirstW, CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, PROCESSENTRY32W}; use winapi::um::winnt::HANDLE; use winapi::um::handleapi::CloseHandle; use std::mem::size_of; use std::ffi::OsString; use std::os::windows::ffi::OsStringExt; fn get_processes() { let h_process_snap: HANDLE; let mut pe32 = PROCESSENTRY32W { dwSize: 0, cntUsage: 0, th32ProcessID: 0, th32DefaultHeapID: 0, th32ModuleID: 0, cntThreads: 0, th32ParentProcessID: 0, pcPriClassBase: 0, dwFlags: 0, szExeFile: [0; 260], }; unsafe { h_process_snap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); } pe32.dwSize = size_of::<PROCESSENTRY32W>() as u32; unsafe { if Process32FirstW(h_process_snap, &mut pe32) == 0 { CloseHandle(h_process_snap); println!("无法获取进程快照"); return; } // 打印Process32FirstW获取到的第一个进程 let exe_name_slice = pe32.szExeFile.split(|&c| c == 0).next().unwrap_or_default(); let exe_name = OsString::from_wide(exe_name_slice).to_string_lossy(); println!("{}", exe_name); while Process32NextW(h_process_snap, &mut pe32) != 0 { let exe_name_slice = pe32.szExeFile.split(|&c| c == 0).next().unwrap_or_default(); let exe_name = OsString::from_wide(exe_name_slice).to_string_lossy(); println!("{}", exe_name); } // 释放快照句柄,避免资源泄漏 CloseHandle(h_process_snap); } }
注意事项
- 如果当前拿到的是u8类型的数组,说明你使用的是ANSI版本的API,这种情况下需要额外处理ANSI编码到UTF-8的转换,实现复杂且容易出现乱码,不推荐使用。
to_string_lossy方法会把无法识别的字符替换为�,避免程序因为编码异常崩溃。
内容的提问来源于stack exchange,提问作者Stef
相关产品推荐
相关产品推荐

