Spot on that seems to work. For future reference, the code I'm now using is:
extern crate winapi;
extern crate kernel32;
extern crate wio;
use kernel32::{CreateToolhelp32Snapshot, Process32FirstW, Process32NextW, CloseHandle};
use winapi::tlhelp32::{TH32CS_SNAPPROCESS, PROCESSENTRY32W};
use winapi::shlobj::INVALID_HANDLE_VALUE;
use winapi::minwindef::MAX_PATH;
use wio::wide::FromWide;
use std::mem;
use std::ffi::OsString;
#[cfg(target_os="windows")]
pub fn find_pid_by_name(name: &str) -> Option<u32> {
// Create a snapshot of the current processes
let processes_snap_handle = unsafe { CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) };
if processes_snap_handle == INVALID_HANDLE_VALUE {
return None
}
// Initialise a process entry. In order to use `Process32First`, you need to set `dwSize`.
let mut process_entry : PROCESSENTRY32W = PROCESSENTRY32W {
dwSize: mem::size_of::<PROCESSENTRY32W>() as u32,
cntUsage: 0,
th32ProcessID: 0,
th32DefaultHeapID: 0,
th32ModuleID: 0,
cntThreads: 0,
th32ParentProcessID: 0,
pcPriClassBase: 0,
dwFlags: 0,
szExeFile: [0; MAX_PATH],
};
// Get the first process from the snapshot.
match unsafe { Process32FirstW(processes_snap_handle, &mut process_entry) } {
1 => {
// First process worked, loop to find the process with the correct name.
let mut process_success : i32 = 1;
// Loop through all processes until we find one hwere `szExeFile` == `name`.
while process_success == 1 {
// TODO: Compare `szExeFile` to `name`.
let process_name = OsString::from_wide(&process_entry.szExeFile);
match process_name.into_string() {
Ok(s) => {
println!("Found process with id {}: {}", process_entry.th32ProcessID, s);
},
Err(_) => {
println!("Error converting process name for PID {}", process_entry.th32ProcessID);
}
}
process_success = unsafe { Process32NextW(processes_snap_handle, &mut process_entry) };
}
unsafe { CloseHandle(processes_snap_handle) };
Some(6812)
},
0|_ => {
unsafe { CloseHandle(processes_snap_handle) };
None
}
}
}
This appears to work perfectly on my system. Thanks a bunch!