Any way to get all visible windows’ file names in Rust?

I’m looking for a function or a library that would provide the function(s) with which I could get all visible windows’ file names. By file names I mean the files that were used to start the process that is showing the window.

I’v heard of the winapi Rust library and got this code (from ChatGPT lmao):

unsafe fn get_file_name_from_process_id(pid: u32) -> Option<String> {
  // Open the process with PROCESS_QUERY_INFORMATION | PROCESS_VM_READ permissions
  let process_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, 0, pid);
  if process_handle.is_null() {
      return None;
  }

  // Get Length of the process image name
  let mut size: u32 = 0;
  QueryFullProcessImageNameW(process_handle, 0, ptr::null_mut(), &mut size);

  // Allocate a buffer for the process image name
  let mut buffer: Vec<u16> = Vec::with_capacity(size as usize);

  // Get the process image name
  if QueryFullProcessImageNameW(process_handle, 0, buffer.as_mut_ptr(), &mut size) != 0 {
    // Convert the buffer to a Rust String
    let process_path = OsString::from_wide(&buffer).to_string_lossy().into_owned();

    // Get the file name from the process path
    if let Some(file_name) = Path::new(&process_path).file_name().and_then(|s| s.to_str()) {
      CloseHandle(process_handle);

      Some(file_name.to_string())
    } else {
      // Close the handle in case of failure
      CloseHandle(process_handle);

      None
    }
  } else {
    // Close the handle in case of failure
    CloseHandle(process_handle);

    None
  }
}

And then I use this to get the file name:

  let file_name: String = get_file_name_from_process_id(GetWindowThreadProcessId(hwnd, ptr::null_mut())).unwrap_or("default".to_string());

but I always get “default” (it’s failing).

  • Add some debug prints between each operation to figure out where it’s failing. For instance, perhaps GetWindowsThreadProcessId is failing before even getting to the function. Or maybe OpenProcess is failing.

    – 




  • 2

    That’s a rather odd problem to want to solve. It is usually the precursor to an XY Problem. Other than that, it pretty much boils down to enumerating all “visible” windows (which is rather complicated), calling GetWindowThreadProcessId() for each window, opening the process and asking for the process image.

    – 

Leave a Comment