feat(exe): add regex, find and use exe name for proton/wine processes in ui

This commit is contained in:
Rerence1016 2025-08-01 20:22:42 +08:00 committed by Pancake
parent da16437210
commit bee751e16b
3 changed files with 31 additions and 5 deletions

1
ui/Cargo.lock generated
View file

@ -690,6 +690,7 @@ dependencies = [
"libadwaita", "libadwaita",
"proc-maps", "proc-maps",
"procfs", "procfs",
"regex",
"serde", "serde",
"toml 0.9.2", "toml 0.9.2",
] ]

View file

@ -11,6 +11,7 @@ toml = "0.9.2"
anyhow = "1.0" anyhow = "1.0"
procfs = "0.17.0" procfs = "0.17.0"
proc-maps = "0.4.0" proc-maps = "0.4.0"
regex = "1.11.1"
[build-dependencies] [build-dependencies]
glib-build-tools = "0.21.0" glib-build-tools = "0.21.0"

View file

@ -1,27 +1,51 @@
use procfs::{process, ProcResult}; use procfs::{process, ProcResult};
use regex::Regex;
pub fn find_vulkan_processes() -> ProcResult<Vec<(String, String)>> { pub fn find_vulkan_processes() -> ProcResult<Vec<(String, String)>> {
// Extract just .exe name from a running Wine or Proton process
let pattern = Regex::new(r"[-\w\s\.()\[\]!@]*(\.[Ee][Xx][Ee])").unwrap();
let mut processes = Vec::new(); let mut processes = Vec::new();
let apps = process::all_processes()?; let apps = process::all_processes()?;
for app in apps { for app in apps {
let Ok(prc) = app else { continue; }; let Ok(process) = app else { continue; };
// ensure vulkan is loaded // ensure vulkan is loaded
let Ok(maps) = proc_maps::get_process_maps(prc.pid()) else { let Ok(maps) = proc_maps::get_process_maps(process.pid()) else {
continue; continue;
}; };
let result = maps.iter() let result = maps.iter()
.filter_map(|map| map.filename()) .filter_map(|map| map.filename())
.map(|filename| filename.to_string_lossy().to_string()) .map(|filename| filename.to_string_lossy().to_string())
.any(|filename| filename.to_lowercase().contains("vulkan")); .any(|filename| filename.to_lowercase().contains("vulkan"));
if !result { if !result {
continue; continue;
} }
// format process information // format process information
let pid = prc.pid(); let pid = process.pid();
let name = prc.stat()?.comm; let name: String;
let process_info = format!("PID {}: {}", pid, name); let cmdline = process.cmdline()?.join(" ");
// If this is a Proton or Wine process with .exe,
// then extract just the .exe name with RegEx
if cmdline.contains(".exe") {
name = pattern.find(&cmdline)
.unwrap()
.as_str()
.to_string();
} else {
// If just a normal Linux process, then use
// the normal name
name = process.stat()?.comm;
}
let process_info = format!("PID {pid}: {name}");
processes.push((process_info, name)); processes.push((process_info, name));
} }