Posts: 795
Threads: 136
Joined: Feb 2009
Hello Gintaras,
i need a little push here.
I'd like a macro that can launch an action when a specific process ends.
It should be found by name.
I tried several things, but I can't do it by myself.
Ex: when process xxx stops, launch program myprogram.exe
It's should be a monitor thing, i.e real time monitor
Thanks
Posts: 12,087
Threads: 142
Joined: Dec 2002
Posts: 795
Threads: 136
Joined: Feb 2009
yes that is the first thing I did..
but I can't find a way to monitor constantly processes, and act when a certain one is closed.
I tried something like that, but i can't go further
function event pid pidparent $name
event: 1 started, 2 ended, 4 running
ARRAY(int) pids
ARRAY(str) noms
sel event
case [1,4]
EnumProcessesEx &pids &noms 2
IStringMap m=CreateStringMap(3)
and I don't know how to carry on
Posts: 12,087
Threads: 142
Joined: Dec 2002
Is process name unknown? If know, use it in trigger.
Posts: 795
Threads: 136
Joined: Feb 2009
the problem is that i want to act on several process.
The trigger function return empty name variable when a process ends.
If could map running processes in an array and retrieve the name of the program by his pid, i could carry on coding.
Posts: 12,087
Threads: 142
Joined: Dec 2002
If several known processes, easier to use several functions with process trigger.
When using single function for all processes, it will slow down all processes a little, because need several ms to run QM thread.
Posts: 795
Threads: 136
Joined: Feb 2009
Finally, found a way, but need some improvements
function event pid pidparent $name
event: 1 started, 2 ended, 4 running
str+ liste ok ok1 ik
sel event
case [1,4]
ok.format("%s - %i" name pid)
liste.formata("%s - %i[]" name pid)
out liste.len ;;test purpose
liste.addline(ok 1)
case 2
ok1.format("%i" pid)
findrx(liste F"(\w+) - {ok1}" 0 11 ik 1)
if(ik.len) out ik.trim ;; test purpose
ik.all
1. I want to limit the variable named liste to max 64000, by truncating some portion to keep only last lines. But how to truncate it from the beginning? liste.fix seems to do it by the end.
2. I presume the (+) in liste declaration make it available as long as QM is launched. Correct?
3. Is there a better way for you to do that code (less memory usage, better regex etc)?
4. Can i clear qm output in code?
Posts: 12,087
Threads: 142
Joined: Dec 2002
This can be used if want to know names of all ended processes.
Function process_management
Trigger $p 0x3 ""
function [event] [pid] [pidparent] [$name]
;event: 1 started, 2 ended, 4 running
lock ;;prevent using global variables simultaneously by multiple threads
type PIDNAME pid ~name
ARRAY(PIDNAME)+ g_proc
int i found
sel event
,case 0 ;;called from init2 at QM startup. Add pid/name of all processes to g_proc.
,ARRAY(int) ap; ARRAY(str) as
,EnumProcessesEx &ap &as
,g_proc.create(ap.len)
,for(i 0 ap.len) g_proc[i].pid=ap[i]; g_proc[i].name.Swap(as[i])
,
,case 1 ;;process started. Add pid/name to g_proc.
,PIDNAME& r=g_proc[]
,r.pid=pid; r.name=name
,
,if(event=1) out F"process started: pid={pid}, name={name}"
,
,case 2 ;;process ended. Find pid/name in g_proc and remove from g_proc.
,for(i 0 g_proc.len) if(g_proc[i].pid=pid) found=1; break
,if(!found) out F"pid {pid} not found"; ret ;;should never happen
,
,out F"process ended: pid={pid}, name={g_proc[i].name}"
,
,g_proc.remove(i)
Also need to call this function from function init2. If don't have init2, create.
Function init2
Posts: 795
Threads: 136
Joined: Feb 2009
OK, great lesson....
Was not aware of init2 launch session nor the case 0 in function that is called from it. Will rmemeber that.
I did not think about the lock feature neither.
I'll tune your code to suit my need, as always.
But in fact, i did take that array managing path because is seemed to me it would be
lighter/faster to just add lines to a variable than iteration through array.
I was wrong.
For the last one, clean the qm output by code? Possible?
Posts: 12,087
Threads: 142
Joined: Dec 2002
Posts: 795
Threads: 136
Joined: Feb 2009
OK.
Just a precision : suppose i want to act on process for two purposes (run a macro if a process dies AND watch processes for cpu use forinstance).
Can I put two identical functions in init2 which only differ in event 2 code, or is must I code all process exit events in the same functions?
2. Is there a limit in init2 functions number I can put in?
3. Do they run synchronously or sequentially?
Posts: 12,087
Threads: 142
Joined: Dec 2002
Should use single trigger. Using multiple process triggers that watch ALL processes is bad for PC performance.
In init2 can call any number of any fast functions. They run synchronously; QM does not start normally until all finished.
In init2 also can launch several threads with mac. They run asynchronously; QM does not wait.
Posts: 795
Threads: 136
Joined: Feb 2009
|