Open valentinegb opened 3 months ago
Did you give a try to process-viewer
and does it have the same issue? Your code looks correct to me. So maybe the issue is the process name you're using to filter?
process-viewer
doesn't seem to have the same problem. Oddly, searching for the process name exactly wouldn't show it, but searching for the process name in all lowercase always did when it was open. In my code I changed instances of processes_by_name()
to processes_by_exact_name()
, since I do have the exact names of the processes I'm looking for, but regardless the issue persists.
Weird. And when you list all processes, do you see the ones you're looking for?
Nope, not unless they were open before I started checking
(Just did this and then searched in my terminal)
for (_pid, process) in sys.processes() {
trace!("{}", process.name().to_str().unwrap());
}
Your issue is very weird. It is tested in different tests like here: the binary is run then only we refresh processes and it's working on mac as well. I'm really confused about what's going wrong on your side...
I cloned sysinfo
and ran all the tests, all passed except test_environ
(not sure if that's related)
---- test_environ stdout ----
thread 'test_environ' panicked at tests/process.rs:158:9:
assertion failed: proc_.environ().iter().any(|e| *e == *env)
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
It may be worth noting that I'm on macOS 15.1 Beta (24B5024e), though I read through the release notes and didn't see any indication that this is a known issue
This one is flaky (on mac). For some reasons, sometimes it cannot retrieve process environment. No clue why. It's part of mac's "magic". ^^'
But if all tests pass, it seems to mean that the problem might not be directly in sysinfo
. Maybe there is something slightly different you do which triggers this result? If we can find out what it is, it'd be awesome so that it can be either be fixed directly in sysinfo
or at least be mentioned in the docs that this one thing should be done differently.
Here's pretty much all the code that currently is actually used in my program:
// main.rs
use std::{error::Error, process::ExitCode};
use discord_rich_presence::{DiscordIpc, DiscordIpcClient};
use log::{debug, error, trace};
use sysinfo::{ProcessRefreshKind, ProcessesToUpdate};
const CLIENT_ID: &str = "1273805325954187386";
fn try_main() -> Result<(), Box<dyn Error>> {
env_logger::init();
debug!("Initialized logging");
if !sysinfo::IS_SUPPORTED_SYSTEM {
return Err("This system is not supported by sysinfo, a crucial dependency".into());
}
let mut sys = sysinfo::System::new();
let mut discord_client = None;
loop {
sys.refresh_processes_specifics(ProcessesToUpdate::All, ProcessRefreshKind::new());
let discord_is_open = sys
.processes_by_exact_name("Discord".as_ref())
.next()
.is_some();
let apple_music_is_open = sys
.processes_by_exact_name("Music".as_ref())
.next()
.is_some();
if discord_is_open && apple_music_is_open {
trace!("Time to work!");
if discord_client.is_none() {
discord_client = Some(DiscordIpcClient::new(CLIENT_ID)?);
discord_client.as_mut().unwrap().connect()?;
debug!("Connected Discord client");
}
// TODO
} else {
trace!("Idling...");
}
}
}
fn main() -> ExitCode {
if let Err(err) = try_main() {
error!("{err}");
return ExitCode::FAILURE;
}
ExitCode::SUCCESS // Impossible to reach?
}
# Cargo.toml
[package]
name = "apple-music-rich-presence"
version = "0.1.0"
edition = "2021"
[dependencies]
discord-rich-presence = { git = "https://github.com/vionya/discord-rich-presence.git", rev = "5620e8901566290a583f9354205686b18628ba1b", version = "0.2.4" }
env_logger = "0.11.5"
log = "0.4.22"
sysinfo = { version = "0.31.2", default-features = false, features = ["system"] }
Some stuff was omitted since it's old and not actually used
Sorry for the massive comment! You would think most of this couldn't be causing this issue but, who knows
Your code looks good. Then let's try taking a different approach: if you ask for the PIDs when you start the program and then see what information sysinfo
has for both processes maybe? I'm curious to see if an information in particular is badly retrieved.
I switched out refresh_processes_specifics()
for refresh_processes()
and added this to the loop:
for (pid, process) in sys.processes() {
trace!("{pid}: {process:?}");
}
Launched Discord and Apple Music then the program. Found those two in the logs:
[2024-08-17T19:58:24Z TRACE apple_music_rich_presence] 11848: Process { pid: Pid(11848), parent: Some(Pid(1)), name: "Discord", environ: [], command: [], executable path: Some("/Applications/Discord.app/Contents/MacOS/Discord"), current working directory: None, memory usage: 48381952, virtual memory usage: 1635724623872, CPU usage: 0.0, status: Run, root: None, disk_usage: DiskUsage { total_written_bytes: 13795328, written_bytes: 0, total_read_bytes: 245784576, read_bytes: 0 }, user_id: Some(Uid(501)), effective_user_id: Some(Uid(501)) }
[2024-08-17T19:58:24Z TRACE apple_music_rich_presence] 15340: Process { pid: Pid(15340), parent: Some(Pid(1)), name: "Music", environ: [], command: [], executable path: Some("/System/Applications/Music.app/Contents/MacOS/Music"), current working directory: None, memory usage: 141099008, virtual memory usage: 426729963520, CPU usage: 0.0, status: Run, root: None, disk_usage: DiskUsage { total_written_bytes: 630784, written_bytes: 0, total_read_bytes: 93708288, read_bytes: 0 }, user_id: Some(Uid(501)), effective_user_id: Some(Uid(501)) }
Another very strange thing I noticed is that programs (such as "VisualizerService") which are launched alongside Apple Music, are detected by sysinfo
when Apple Music is launched afterwards, even though Apple Music itself is not. Here's the logging of VisualizerService, too:
[2024-08-17T19:58:24Z TRACE apple_music_rich_presence] 15341: Process { pid: Pid(15341), parent: Some(Pid(1)), name: "VisualizerService", environ: [], command: [], executable path: Some("/System/Applications/Music.app/Contents/XPCServices/VisualizerService.xpc/Contents/MacOS/VisualizerService"), current working directory: None, memory usage: 15843328, virtual memory usage: 420849057792, CPU usage: 0.0, status: Run, root: None, disk_usage: DiskUsage { total_written_bytes: 0, written_bytes: 0, total_read_bytes: 348160, read_bytes: 0 }, user_id: Some(Uid(501)), effective_user_id: Some(Uid(501)) }
Definitely strange. refresh_processes
calls refresh_processes_specifics
as you can see here. So there is definitely something wrong in sysinfo
. Since I can't replicate the bug locally, do you mind trying to find out what's wrong in the source code please? ^^'
Don't hesitate to ask if you have any question. But I'm glad that a new bug was found. :D
A revelation! This code fixed the issue:
sleep(Duration::from_secs(5));
... So the problem is that the loop is too fast when not limited?
Wait really? If true then it's really not great. T_T
sysinfo
uses proc_listallpids
to retrieve all PIDs and then iterate through them. It'd be super weird for this API to take multiple seconds to realize a process got added...
Did a little bit of testing, I was able to get as low as 1 second to consistently detect processes correctly, and as low as 100 milliseconds to inconsistently detect processes correctly
But no process with the given PID you're looking for is there right? If so, I suppose the proc_listallpids
function is not working correctly...
But no process with the given PID you're looking for is there right?
If there's some time between refreshes, the processes I'm looking for do appear.
So it seems like the system API is not refreshing very quickly. How strange.
Describe the bug
It seems that if a program is using
sysinfo
to check the processes currently running and a new process starts later, it won't be added to the list of processes despite refreshing. Inexplicably, though, while this happens most of the time, there are some times where a newly launched program will be detected.sysinfo
version: 0.31.2sysinfo
features:system
To Reproduce