将 tchar 数组打印为 unicode 字符串 rust winapi
Printing tchar array as unicode string rust winapi
我正在使用 winapi 获取系统上当前进程的列表 运行,这是我的代码:
use winapi::um::tlhelp32::{Process32Next, Process32First, CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, PROCESSENTRY32};
use winapi::um::winnt::HANDLE;
use winapi::um::handleapi::CloseHandle;
use std::mem::size_of;
...
fn get_processes() {
let h_process_snap: HANDLE;
// really, rust?
let mut pe32 = &mut PROCESSENTRY32{
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::<PROCESSENTRY32>() as u32;
unsafe {
if Process32First(h_process_snap, pe32) == 0 {
CloseHandle(h_process_snap);
println!("can't get a process snapshot");
// TODO: return
}
while Process32Next(h_process_snap, pe32) != 0 {
println!("{:?}", pe32.szExeFile);
}
}
}
...
现在我正在尝试打印进程的实际名称,在 C++ 中,这可以使用 cout or wcout 来完成。
当我使用 println!("{:?}", pe32.szExeFile);
时,这是我得到的:
[115, 117, 112, 101, 114, 102, 52, 45, 114, 117, 115, 116, 46, 101, 120, 101, 0, 116, 46, 101, 120, 101, 0, 98, 108, 101, 83, 104, 101, 108, 108, 46, 69, 120, 112, 101, 114, 105, 101, 110, 99, 101, 115, 46, 84, 101, 120, 116, 73, 110, 112, 117, 116, 46, 73, 110, 112, 117, 116, 65, 112, 112, 46, 101, 120, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
我不太明白如何使用它,如何在 Rust 中将 pe32.szExeFile 打印为 Unicode 字符串?
另请参阅:https://docs.rs/winapi/0.3.6/winapi/um/tlhelp32/struct.PROCESSENTRY32.html
您的数组看起来像一个可以表示为 [u8;260]
的数组。这告诉我您可以使用 as
:
将每个元素转换为其字符表示
fn main() {
let some_string: [u8; 260] = [115, 117, 112, 101, 114, 102, 52, 45, 114, 117, 115, 116, 46, 101, 120, 101, 0, 116, 46, 101, 120, 101, 0, 98, 108, 101, 83, 104, 101, 108, 108, 46, 69, 120, 112, 101, 114, 105, 101, 110, 99, 101, 115, 46, 84, 101, 120, 116, 73, 110, 112, 117, 116, 46, 73, 110, 112, 117, 116, 65, 112, 112, 46, 101, 120, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
// Represent each u8 from some_string as a char in readable_string
let readable_string: [char;260] = some_string.map(|x| x as char);
for c in readable_string.iter().enumerate() {
let (i, val): (usize, &char) = c;
// Note that some characters are '\u{0}', which could be substituted
// with a space
match val {
'\u{0}' => print!(" "),
_ => print!("{}", val)
};
}
}
以上产生以下输出:
superf4-rust.exe t.exe bleShell.Experiences.TextInput.InputApp.exe
这是你想要做的吗?
感谢@IInspectable,我使用了明确的 Unicode 版本,例如Process32FirstW, and from_wide 以可读格式打印值:
let os_string = OsString::from_wide(&pe32.szExeFile[..]);
// ExeFile names have a lot of trailing 0's, remove them...
let exe_files: String = os_string.into_string().unwrap().replace("\u{0}", "");
println!("{:?}", exe_files);
我正在使用 winapi 获取系统上当前进程的列表 运行,这是我的代码:
use winapi::um::tlhelp32::{Process32Next, Process32First, CreateToolhelp32Snapshot, TH32CS_SNAPPROCESS, PROCESSENTRY32};
use winapi::um::winnt::HANDLE;
use winapi::um::handleapi::CloseHandle;
use std::mem::size_of;
...
fn get_processes() {
let h_process_snap: HANDLE;
// really, rust?
let mut pe32 = &mut PROCESSENTRY32{
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::<PROCESSENTRY32>() as u32;
unsafe {
if Process32First(h_process_snap, pe32) == 0 {
CloseHandle(h_process_snap);
println!("can't get a process snapshot");
// TODO: return
}
while Process32Next(h_process_snap, pe32) != 0 {
println!("{:?}", pe32.szExeFile);
}
}
}
...
现在我正在尝试打印进程的实际名称,在 C++ 中,这可以使用 cout or wcout 来完成。
当我使用 println!("{:?}", pe32.szExeFile);
时,这是我得到的:
[115, 117, 112, 101, 114, 102, 52, 45, 114, 117, 115, 116, 46, 101, 120, 101, 0, 116, 46, 101, 120, 101, 0, 98, 108, 101, 83, 104, 101, 108, 108, 46, 69, 120, 112, 101, 114, 105, 101, 110, 99, 101, 115, 46, 84, 101, 120, 116, 73, 110, 112, 117, 116, 46, 73, 110, 112, 117, 116, 65, 112, 112, 46, 101, 120, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
我不太明白如何使用它,如何在 Rust 中将 pe32.szExeFile 打印为 Unicode 字符串?
另请参阅:https://docs.rs/winapi/0.3.6/winapi/um/tlhelp32/struct.PROCESSENTRY32.html
您的数组看起来像一个可以表示为 [u8;260]
的数组。这告诉我您可以使用 as
:
fn main() {
let some_string: [u8; 260] = [115, 117, 112, 101, 114, 102, 52, 45, 114, 117, 115, 116, 46, 101, 120, 101, 0, 116, 46, 101, 120, 101, 0, 98, 108, 101, 83, 104, 101, 108, 108, 46, 69, 120, 112, 101, 114, 105, 101, 110, 99, 101, 115, 46, 84, 101, 120, 116, 73, 110, 112, 117, 116, 46, 73, 110, 112, 117, 116, 65, 112, 112, 46, 101, 120, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
// Represent each u8 from some_string as a char in readable_string
let readable_string: [char;260] = some_string.map(|x| x as char);
for c in readable_string.iter().enumerate() {
let (i, val): (usize, &char) = c;
// Note that some characters are '\u{0}', which could be substituted
// with a space
match val {
'\u{0}' => print!(" "),
_ => print!("{}", val)
};
}
}
以上产生以下输出:
superf4-rust.exe t.exe bleShell.Experiences.TextInput.InputApp.exe
这是你想要做的吗?
感谢@IInspectable,我使用了明确的 Unicode 版本,例如Process32FirstW, and from_wide 以可读格式打印值:
let os_string = OsString::from_wide(&pe32.szExeFile[..]);
// ExeFile names have a lot of trailing 0's, remove them...
let exe_files: String = os_string.into_string().unwrap().replace("\u{0}", "");
println!("{:?}", exe_files);