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

Rust调用WinAPI枚举进程时如何将szExeFile转为Unicode字符串

解决方案

核心原理

PROCESSENTRY32 结构体中的 szExeFile 是Windows原生的宽字符(WCHAR,对应Rust的u16类型)数组,以空字符\0作为结束标志,不能直接通过println!打印数组内容。你需要先截取到空字符前的有效内容,再转换为Rust的字符串类型。

实现步骤

  1. 首先引入Windows字符串转换所需的依赖:
use std::ffi::OsString;
use std::os::windows::ffi::OsStringExt;
  1. 建议优先使用Unicode版本的WinAPI,确保编码正确,需要把原来的API调用替换为带W后缀的版本:
  • Process32First 替换为 Process32FirstW
  • Process32Next 替换为 Process32NextW
  • PROCESSENTRY32 替换为 PROCESSENTRY32W
  1. 在遍历进程的循环中,添加字符串转换逻辑,替换原来的打印代码:
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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 08:30:01