Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

New Process Notifier


  • Please log in to reply
12 replies to this topic
sbc
  • Members
  • 321 posts
  • Last active: Jun 07 2011 10:24 AM
  • Joined: 25 Aug 2009
Screenshot:
Posted Image

Download:
for general Windows users ->NewProcessNotifier.exe (zip)
for AHK users ->NewProcessNotifier1.1.0.ahk.zip (includes icons)

Platform: Windows XP, Vista or later (not tested on W2K but should run.)

Overview: This is a small background script which notifies newly created/closed processes and logs those information.

Version History:
1.1.0 Aug 31, 2010 No more use of tasklist.exe and compatible with XP home.
1.0.1 Aug 17, 2010 No more use of clipboard and compatible with XP Pro.
1.0.0 Aug 17, 2010

Thanks: Lexikos for the demonstration of the COM usage.

  • Guests
  • Last active:
  • Joined: --
nice, but
you could avoid the gap between pre- and post-Vista,
and the messing with the clipboard.

check the Example #4 in http://www.autohotke...nds/Process.htm to see how to obtain the taslist without the use of external programs.

or you could pipe the output of tasklist to a file (or a named pipe) and read from that, instead of using the clipboard.

or you could use CMDRet by Corrupt

sbc
  • Members
  • 321 posts
  • Last active: Jun 07 2011 10:24 AM
  • Joined: 25 Aug 2009
It is updated.

check the Example #4 in http://www.autohotke...nds/Process.htm to see how to obtain the taslist without the use of external programs.

That method seems to have an incompatibility issue with Windows 7.

or you could pipe the output of tasklist to a file (or a named pipe) and read from that, instead of using the clipboard.

I had been looking for a way without creating an external file to read the output.

or you could use CMDRet by Corrupt

This seems to be the most efficient way. Thanks for the suggestion.

  • Guests
  • Last active:
  • Joined: --
great, thanks

Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
I recently wrote a script that detects new or closed processes, as an example of the COM features recently integrated into AutoHotkey_L. I ended up not using the example, but I figured the topic would come up sooner or later. Perhaps you will find it interesting. Requires AutoHotkey_L:
; Get WMI service object.
winmgmts := ComObjGet([color=darkred]"winmgmts:"[/color])

; Create sink objects for receiving event noficiations.
ComObjConnect(createSink := ComObjCreate([color=darkred]"WbemScripting.SWbemSink"[/color]), [color=darkred]"ProcessCreate_")[/color]
ComObjConnect(deleteSink := ComObjCreate([color=darkred]"WbemScripting.SWbemSink"[/color]), [color=darkred]"ProcessDelete_"[/color])

; Set event polling interval, in seconds.
interval := 2

; Register for process creation notifications:
winmgmts.ExecNotificationQueryAsync(createSink
    , [color=darkred]"Select * from __InstanceCreationEvent"[/color]
    . [color=darkred]" within "[/color] interval
    . [color=darkred]" where TargetInstance isa 'Win32_Process'"[/color])

; Register for process deletion notifications:
winmgmts.ExecNotificationQueryAsync(deleteSink
    , [color=darkred]"Select * from __InstanceDeletionEvent"[/color]
    . [color=darkred]" within "[/color] interval
    . [color=darkred]" where TargetInstance isa 'Win32_Process'"[/color])

; Don't exit automatically.
#Persistent

; Called when a new process is detected:
ProcessCreate_OnObjectReady(obj) {
    proc := obj.TargetInstance
    TrayTip New Process Detected, % [color=darkred]"[/color]
    [color=darkgray](LTrim[/color]
        [color=darkred]ID:`t"[/color] proc.ProcessID [color=darkred]"
        Parent:`t"[/color] proc.ParentProcessID [color=darkred]"
        Name:`t"[/color] proc.Name [color=darkred]"
        Path:`t"[/color] proc.ExecutablePath [color=darkred]"
        
        Command line (requires XP or later):
        
        "[/color] proc.CommandLine
    [color=darkgray])[/color]
}

; Called when a process terminates:
ProcessDelete_OnObjectReady(obj) {
    proc := obj.TargetInstance
    TrayTip Process Terminated, % [color=darkred]"[/color]
    [color=darkgray](LTrim[/color]
        [color=darkred]ID:`t"[/color] proc.Handle [color=darkred]"
        Name:`t"[/color] proc.Name
    [color=darkgray])[/color]
}
It can also be written to work (only) on standard AutoHotkey. This version requires COM Standard Library:
COM_Init()

; Get WMI service object.
winmgmts := COM_GetObject([color=darkred]"winmgmts:"[/color])

; Create sink objects for receiving event noficiations.
COM_ConnectObject(createSink := COM_CreateObject([color=darkred]"WbemScripting.SWbemSink"[/color]), [color=darkred]"ProcessCreate_"[/color])
COM_ConnectObject(deleteSink := COM_CreateObject([color=darkred]"WbemScripting.SWbemSink"[/color]), [color=darkred]"ProcessDelete_"[/color])

; Set event polling interval, in seconds.
interval := 2

; Register for process creation notifications:
COM_Invoke(winmgmts, [color=darkred]"ExecNotificationQueryAsync"[/color], [color=darkred]"+"[/color] createSink
    , [color=darkred]"Select * from __InstanceCreationEvent"[/color]
    . [color=darkred]" within "[/color] interval
    . [color=darkred]" where TargetInstance isa 'Win32_Process'"[/color])

; Register for process deletion notifications:
COM_Invoke(winmgmts, [color=darkred]"ExecNotificationQueryAsync"[/color], [color=darkred]"+"[/color] deleteSink
    , [color=darkred]"Select * from __InstanceDeletionEvent"[/color]
    . [color=darkred]" within "[/color] interval
    . [color=darkred]" where TargetInstance isa 'Win32_Process'"[/color])

; Don't exit automatically.
#Persistent

; Called when a new process is detected:
ProcessCreate_OnObjectReady(prm) {
    obj := COM_DispGetParam(prm, 0, 9)
    proc := COM_Invoke(obj, [color=darkred]"TargetInstance"[/color])
    COM_Release(obj)
    TrayTip New Process Detected, % [color=darkred]"[/color]
    [color=darkgray](LTrim[/color]
        [color=darkred]ID:`t"[/color] COM_Invoke(proc, [color=darkred]"ProcessID"[/color]) [color=darkred]"
        Parent:`t"[/color] COM_Invoke(proc, [color=darkred]"ParentProcessID"[/color]) [color=darkred]"
        Name:`t"[/color] COM_Invoke(proc, [color=darkred]"Name"[/color]) [color=darkred]"
        Path:`t"[/color] COM_Invoke(proc, [color=darkred]"ExecutablePath"[/color]) [color=darkred]"
        
        Command line (requires XP or later):
        
        "[/color] COM_Invoke(proc, [color=darkred]"CommandLine"[/color])
    )
    COM_Release(proc)
}

; Called when a process terminates:
ProcessDelete_OnObjectReady(prm) {
    obj := COM_DispGetParam(prm, 0, 9)
    proc := COM_Invoke(obj, [color=darkred]"TargetInstance"[/color])
    COM_Release(obj)
    TrayTip Process Terminated, % [color=darkred]"[/color]
    [color=darkgray](LTrim[/color]
        [color=darkred]ID:`t"[/color] COM_Invoke(proc, [color=darkred]"Handle"[/color]) [color=darkred]"
        Name:`t"[/color] COM_Invoke(proc, [color=darkred]"Name"[/color])
    )
    COM_Release(proc)
}
Feel free to use any part of the script however you like.

Btw, XP Home does not include tasklist.exe.

sbc
  • Members
  • 321 posts
  • Last active: Jun 07 2011 10:24 AM
  • Joined: 25 Aug 2009
Just amazing... :O

Is it possible to get the User Name who created a process with COM?

I looked at this page, <!-- m -->http://msdn.microsof...ry ... 85).aspx<!-- m --> and could pull out some of the elements like,

Time:`t" COM_Invoke(proc, "CreationDate") "
Size:`t" COM_Invoke(proc, "VirtualSize") "
but not with GetOwner. It seems I need to learn how to use COM first.

  • Guests
  • Last active:
  • Joined: --

That method seems to have an incompatibility issue with Windows 7.

...do you have any more information on this? I used Example 4 to create my ProcessGet() function, so I'd need to have someone test it & report what don't work on Win7 (& Vista). So, assuming you already tried the Example 4 code, what didn't work?...or technically, exactly what does happen, when you try it?

sbc
  • Members
  • 321 posts
  • Last active: Jun 07 2011 10:24 AM
  • Joined: 25 Aug 2009

I'd need to have someone test it & report what don't work on Win7 (& Vista).


Ok, here is the report from XP(32bit) and 7(64bit). I used the exact code from the manual (Process:Example#4) quoted below.
; Example #4: Retrieves a list of running processes via DllCall then shows them in a MsgBox.

d = `n  ; string separator
s := 4096  ; size of buffers and arrays (4 KB)

Process, Exist  ; sets ErrorLevel to the PID of this running script
; Get the handle of this script with PROCESS_QUERY_INFORMATION (0x0400)
h := DllCall("OpenProcess", "UInt", 0x0400, "Int", false, "UInt", ErrorLevel)
; Open an adjustable access token with this process (TOKEN_ADJUST_PRIVILEGES = 32)
DllCall("Advapi32.dll\OpenProcessToken", "UInt", h, "UInt", 32, "UIntP", t)
VarSetCapacity(ti, 16, 0)  ; structure of privileges
NumPut(1, ti, 0)  ; one entry in the privileges array...
; Retrieves the locally unique identifier of the debug privilege:
DllCall("Advapi32.dll\LookupPrivilegeValueA", "UInt", 0, "Str", "SeDebugPrivilege", "Int64P", luid)
NumPut(luid, ti, 4, "int64")
NumPut(2, ti, 12)  ; enable this privilege: SE_PRIVILEGE_ENABLED = 2
; Update the privileges of this process with the new access token:
DllCall("Advapi32.dll\AdjustTokenPrivileges", "UInt", t, "Int", false, "UInt", &ti, "UInt", 0, "UInt", 0, "UInt", 0)
DllCall("CloseHandle", "UInt", h)  ; close this process handle to save memory

hModule := DllCall("LoadLibrary", "Str", "Psapi.dll")  ; increase performance by preloading the libaray
s := VarSetCapacity(a, s)  ; an array that receives the list of process identifiers:
c := 0  ; counter for process idendifiers
DllCall("Psapi.dll\EnumProcesses", "UInt", &a, "UInt", s, "UIntP", r)
Loop, % r // 4  ; parse array for identifiers as DWORDs (32 bits):
{
   id := NumGet(a, A_Index * 4)
   ; Open process with: PROCESS_VM_READ (0x0010) | PROCESS_QUERY_INFORMATION (0x0400)
   h := DllCall("OpenProcess", "UInt", 0x0010 | 0x0400, "Int", false, "UInt", id)
   VarSetCapacity(n, s, 0)  ; a buffer that receives the base name of the module:
   e := DllCall("Psapi.dll\GetModuleBaseNameA", "UInt", h, "UInt", 0, "Str", n, "UInt", s)
   DllCall("CloseHandle", "UInt", h)  ; close process handle to save memory
   if (n && e)  ; if image is not null add to list:
      l .= n . d, c++
}
DllCall("FreeLibrary", "UInt", hModule)  ; unload the library to free memory
;Sort, l, C  ; uncomment this line to sort the list alphabetically
MsgBox, 0, %c% Processes, %l%

It does not detect all the tasks on 7(64bit) but seems to function on XP.

XP tasklist.exe & AHK Process Listing Script from Manual Example #4
Posted Image
<!-- m -->http://lh6.ggpht.com... ... hoot01.png<!-- m -->

Windows 7 tasklist.exe & AHK Process Listing Script from Manual Example #4
Posted Image
<!-- m -->http://lh5.ggpht.com... ... hoot02.png<!-- m -->

Windows 7 Task Manater indicates the number of running processes
Posted Image
<!-- m -->http://lh3.ggpht.com... ... hoot03.png<!-- m -->


By the way, running more than 24 hours of this script on the XP machine is getting huge on the memory usage..... :O It's no happening on my 7(64bit).

AHK Script Getting Large of Memory Usage
Posted Image
<!-- m -->http://lh4.ggpht.com... ... blem01.png<!-- m -->

lexios
  • Guests
  • Last active:
  • Joined: --

Is it possible to get the User Name who created a process with COM?

Yes. GetOwner uses ByRef parameters.
global user, domain  ; If in a function.
    COM_Invoke_(proc, [color=darkred]"GetOwner"[/color], 0x4008, [color=darkred]"user"[/color], 0x4008, [color=darkred]"domain"[/color])
    MsgBox % user [color=darkred]" "[/color] domain
0x4008 is a combination of VT_BYREF (0x4000) and VT_BSTR (8). More code is needed for AutoHotkey_L as it doesn't directly support ByRef parameters.

nrk112
  • Members
  • 8 posts
  • Last active: Apr 01 2013 06:41 AM
  • Joined: 16 Sep 2011

Hi, maybe someone can help me. I realize this is an old thread but I cant find this information elsewhere. 

 For lexikos example autohotkey_l

 

It seems to detect new processes starting and stopping but when the traytip pops up, it shows the code verbatim.  I.E. "proc.ProcessID" shows instead of the process ID.  The proc variable seems to be empty at that point which I assume is whats causing the problem, but this code is beyond me and I cant figure out why that is. 

 

Any help would be greatly appreciated!  Thanks



Lexikos
  • Administrators
  • 9844 posts
  • AutoHotkey Foundation
  • Last active:
  • Joined: 17 Oct 2006
For it to literally show proc.ProcessID, you must have copied the script incorrectly. It's easy to do, since the code is littered with color tags that shouldn't be there. If you do MsgBox % proc and it contains an object, it will "appear empty" because an object cannot be implicitly converted to a string.

mia
  • Members
  • 73 posts
  • Last active: Jul 26 2014 09:28 AM
  • Joined: 05 Aug 2013

Hi! :shy:

 

I think i successfully edited the code above. At first it didnt work at least two error. Now working fine.

 

Help!

I wanted to auto close any new process using the code below. Can someone do the code for me :D . Please.. :shy: .

 

; ========== START OF SCRIPT ==========

 

; Get WMI service object.
winmgmts := ComObjGet("winmgmts:")

; Create sink objects for receiving event noficiations.
ComObjConnect(createSink := ComObjCreate("WbemScripting.SWbemSink"), "ProcessCreate_")
ComObjConnect(deleteSink := ComObjCreate("WbemScripting.SWbemSink"), "ProcessDelete_")

; Set event polling interval, in seconds.
interval := 2

; Register for process creation notifications:
winmgmts.ExecNotificationQueryAsync(createSink
    , "Select * from __InstanceCreationEvent"
    . " within " interval
    . " where TargetInstance isa 'Win32_Process'")

; Register for process deletion notifications:
winmgmts.ExecNotificationQueryAsync(deleteSink
    , "Select * from __InstanceDeletionEvent"
    . " within " interval
    . " where TargetInstance isa 'Win32_Process'")

; Don't exit automatically.
#Persistent

; Called when a new process is detected:
ProcessCreate_OnObjectReady(obj) {
    proc := obj.TargetInstance
    TrayTip New Process Detected, % "
    (LTrim
        ID:`t" proc.ProcessID "
        Parent:`t" proc.ParentProcessID "
        Name:`t" proc.Name "
        Path:`t" proc.ExecutablePath "
        
        Command line (requires XP or later):
        
        " proc.CommandLine
)

}

; Called when a process terminates:
ProcessDelete_OnObjectReady(obj) {
    proc := obj.TargetInstance
    TrayTip Process Terminated, % "
    (LTrim
        ID:`t" proc.Handle "
        Name:`t" proc.Name
)

}
 

; ========== END OF SCRIPT ==========

 

 

Thanks in advance.

 

mia :shy: :D



Xavier
  • Members
  • 2 posts
  • Last active: Jan 17 2014 12:11 PM
  • Joined: 09 Oct 2013

MIA's edited script works fine on Windows 8.1 with no errors.  How to include logging functions?