Skip to content

Commit 0c629f0

Browse files
committed
feat: support process tree
1 parent ea98be9 commit 0c629f0

File tree

2 files changed

+33
-17
lines changed

2 files changed

+33
-17
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ You can customize it's blacklist. It's by default a set of decompressors.
2323
- [x] Multi Window support
2424
- [x] Child processes support
2525
- [x] Direct child processes
26-
- [ ] Process tree walking
26+
- [x] Process tree walking
2727
- [x] Event-based foreground window boost
2828
- [x] Event-based throttle for all new processes
2929
- [x] Recover processes on exit

src/utils/mod.rs

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use std::collections::BTreeMap;
2+
13
use spdlog::{info, warn};
24
use win32_ecoqos::{
35
process::toggle_efficiency_mode,
@@ -7,47 +9,61 @@ use win32_ecoqos::{
79

810
use crate::bypass::should_bypass;
911

10-
pub fn process_child_process(enable: Option<bool>, pid: u32) -> windows_result::Result<()> {
12+
pub fn process_child_process(enable: Option<bool>, main_pid: u32) -> windows_result::Result<()> {
1113
let action = match enable {
1214
Some(true) => "throtting",
1315
Some(false) => "boosting ",
1416
None => "recovering",
1517
};
1618

17-
let procs = Processes::try_new()?
18-
.filter(
19-
|&Process {
20-
process_id,
21-
process_parent_id,
22-
..
23-
}| { process_id == pid || process_parent_id == pid },
24-
)
25-
.collect::<Vec<_>>();
19+
let procs = Processes::try_new()?.collect::<Vec<_>>();
2620

2721
if let Some(Process { process_name, .. }) = procs
2822
.iter()
29-
.find(|Process { process_id, .. }| process_id == &pid)
23+
.find(|Process { process_id, .. }| process_id == &main_pid)
3024
{
3125
if should_bypass(process_name) {
3226
info!("skipping whitelisted process: {process_name:?}");
3327
return Ok(());
3428
}
3529

36-
info!("{action} process {pid:6}: {process_name:?}");
30+
info!("{action} process {main_pid:6}: {process_name:?}");
3731
} else {
38-
info!("{action} process {pid:6}");
32+
info!("{action} process {main_pid:6}");
3933
}
4034

35+
let relations = BTreeMap::from_iter(procs.iter().map(
36+
|Process {
37+
process_id,
38+
process_parent_id,
39+
..
40+
}| (process_id, process_parent_id),
41+
));
42+
let in_process_tree = |mut pid: u32| {
43+
while let Some(&&parent_pid) = relations.get(&pid) {
44+
if parent_pid == main_pid {
45+
return true;
46+
}
47+
48+
pid = parent_pid;
49+
}
50+
51+
false
52+
};
53+
4154
for Process {
4255
process_id,
4356
process_name,
4457
..
45-
} in procs
58+
} in &procs
4659
{
47-
if should_bypass(&process_name) {
60+
if !in_process_tree(*process_id) {
61+
continue;
62+
}
63+
if should_bypass(process_name) {
4864
continue;
4965
}
50-
if let Err(e) = toggle_efficiency_mode(process_id, enable) {
66+
if let Err(e) = toggle_efficiency_mode(*process_id, enable) {
5167
warn!("failed to toggle {process_name:?}: {e}");
5268
}
5369
}

0 commit comments

Comments
 (0)