diff --git a/src/utils/utils.cpp b/src/utils/utils.cpp index a264833..e405423 100644 --- a/src/utils/utils.cpp +++ b/src/utils/utils.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include #include @@ -19,7 +20,6 @@ #include #include #include -#include using namespace Utils; @@ -237,29 +237,22 @@ std::pair Utils::getProcessName() { // For .exe apps running through Proton/Wine - std::ifstream cmdline_file("/proc/self/cmdline"); - if (!cmdline_file.is_open()) { - return {"", ""}; // Not sure what to do if it ISN'T open - } - std::string cmdline; - getline(cmdline_file, cmdline, '\0'); + std::ifstream maps_file("/proc/self/maps"); + std::string line; - // If the process is a Proton/Wine app - if (cmdline.find(".exe") != std::string::npos) { + while (getline(maps_file, line)) { + if (line.find(".exe") != std::string::npos) { - // Extract just the executable name - std::regex pattern(R"([-\w\s\.()\[\]!@]*(\.[Ee][Xx][Ee]))"); - std::smatch match; - if (std::regex_search(cmdline, match, pattern)) { - comm_str = match[0]; - } - } else { - - // If it's not a .exe app, just use the comm string - - // Note: if not a Windows app, the name will still be - // cut off to just 15 characters as a limitation of - // using comm in /proc + // Backslash needs to be a raw string literal + size_t path_start = line.find("/") || line.find(R"(\)"); + if (path_start != std::string::npos) { + std::string path = line.substr(path_start); + comm_str = std::filesystem::path(path).filename().string(); + } else { + // If nothing found, default to 0 + path_start = 0; + } + } } return{ std::string(exe.data()), comm_str }; diff --git a/ui/src/utils.rs b/ui/src/utils.rs index 0d6e5d5..024b68c 100644 --- a/ui/src/utils.rs +++ b/ui/src/utils.rs @@ -1,11 +1,7 @@ use procfs::{process, ProcResult}; -use regex::Regex; +use std::path::Path; pub fn find_vulkan_processes() -> ProcResult> { - - // 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 apps = process::all_processes()?; @@ -26,25 +22,38 @@ pub fn find_vulkan_processes() -> ProcResult> { continue; } - // format process information + // Format process information + let pid = process.pid(); - let name: String; + + // By default, assume Linux process, and use comm + let mut name = process.stat()?.comm; + + // Solely just for checking if it's a Proton or Wine process + // Not sure if there's a more efficient way to do this 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 { + for map in &maps { + if let Some(path) = map.filename() { + let path_str = path.to_string_lossy().to_lowercase(); + if path_str.contains(".exe") && + !path_str.contains("wine") && + path_str.contains('/') || + path_str.contains('\\') { - // If just a normal Linux process, then use - // the normal name - name = process.stat()?.comm; + name = Path::new(&path_str).file_name() + .unwrap_or_default() + .to_string_lossy() + .to_string(); + break; + } + } + } } - let process_info = format!("PID {pid}: {name}"); processes.push((process_info, name)); }