Here's something I did a few years ago -- a fairly clumsy way of doing it, but it seems to work quite well:
Code: Select all
; -----------------------------------------------------------------------------
; MAKE SURE DEBUGGER IS ON!!!
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; GetWindowsFamily () returns #VER_PLATFORM_WIN32_NT (NT, 2000, XP, etc) or
; #VER_PLATFORM_WIN32_WINDOWS (95, 98). Process entries have no paths under NT.
; -----------------------------------------------------------------------------
Procedure GetWindowsFamily ()
os.OSVERSIONINFO
os\dwOSVersionInfoSize = SizeOf (OSVERSIONINFO)
GetVersionEx_ (@os)
ProcedureReturn os\dwPlatformId
EndProcedure
; -----------------------------------------------------------------------------
; Constants required...
; -----------------------------------------------------------------------------
; Process access rights...
#PROCESS_TERMINATE = $1
#PROCESS_CREATE_THREAD = $2
#PROCESS_VM_OPERATION = $8
#PROCESS_VM_READ = $10
#PROCESS_VM_WRITE = $20
#PROCESS_DUP_HANDLE = $40
#PROCESS_CREATE_PROCESS = $80
#PROCESS_SET_QUOTA = $100
#PROCESS_SET_INFORMATION = $200
#PROCESS_QUERY_INFORMATION = $400
#PROCESS_ALL_ACCESS = #STANDARD_RIGHTS_REQUIRED | #SYNCHRONIZE | $FFF
; Snapshot requirements...
#TH32CS_SNAPHEAPLIST = $1
#TH32CS_SNAPPROCESS = $2
#TH32CS_SNAPTHREAD = $4
#TH32CS_SNAPMODULE = $8
#TH32CS_SNAPALL = #TH32CS_SNAPHEAPLIST | #TH32CS_SNAPPROCESS | #TH32CS_SNAPTHREAD | #TH32CS_SNAPMODULE
#TH32CS_INHERIT = $80000000
#INVALID_HANDLE_VALUE = -1
; Library numbers (psapi.dll on NT and kernel32.dll)...
#PSAPILIB = 9
#KERNEL32LIB = 10
NewList Process2.s ()
first_run = 1
restart:
NewList Process1.s ()
NewList NewProcess.s ()
; Get process list...
If OpenLibrary (#KERNEL32LIB, "kernel32.dll")
snap = CallFunction (#KERNEL32LIB, "CreateToolhelp32Snapshot", #TH32CS_SNAPPROCESS, 0)
If snap
Proc32.PROCESSENTRY32
Proc32\dwSize = SizeOf (PROCESSENTRY32)
If CallFunction (#KERNEL32LIB, "Process32First", snap, @Proc32)
While CallFunction (#KERNEL32LIB, "Process32Next", snap, @Proc32)
If OpenLibrary (#PSAPILIB, "psapi.dll")
handle = OpenProcess_ (#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, 0, Proc32\th32ProcessID)
If handle
If CallFunction (#PSAPILIB, "EnumProcessModules", handle, @module, 4, @needed)
f$ = Space (#MAX_PATH)
If CallFunction (#PSAPILIB, "GetModuleFileNameExA", handle, module, @f$, #MAX_PATH)
AddElement (Process1 ())
Process1 () = f$
exists = 0
ResetList (Process2 ())
While NextElement (Process2 ())
If Process1 () = Process2 ()
exists = exists + 1
EndIf
Wend
; ADD PROCESS ID!
If exists = 0
AddElement (NewProcess ())
NewProcess () = Process1 ()
EndIf
EndIf
EndIf
CloseHandle_ (handle)
EndIf
CloseLibrary (#PSAPILIB)
EndIf
Wend
EndIf
CloseHandle_ (snap)
EndIf
CloseLibrary (#KERNEL32LIB)
EndIf
; NB: userinit.exe used to stay open until all (?) startup programs were running,
; but I'm not sure if this is still the case. This was used to ignore all programs
; if run on startup...
If windows_loaded = 0 ; Only do this loop if windows_loaded = 1
windows_loaded = 1 ; Set to 1, assuming Windows is now loaded...
While NextElement (Process1 ())
If Right (Process1 (), 12) = "userinit.exe" ; Wait, no it's not! Set back to 0...
windows_loaded = 0
Break
EndIf
Wend
EndIf
If windows_loaded ; Will be 1 if userinit.exe has gone...
If Not first_run
If exists = 0
proc$ = ""
proc_count = 0
ResetList (NewProcess ())
While NextElement (NewProcess ())
proc$ = proc$ + NewProcess () + Chr (10)
proc_count = proc_count + 1
Wend
If proc_count > 1
p$ = "es"
Else
p$ = ""
EndIf
Debug "New process" + p$ + " started: " + proc$
EndIf
Else
first_run = 0
EndIf
EndIf
ResetList (Process1 ())
ClearList (Process2 ())
While NextElement (Process1 ())
AddElement (Process2 ())
Process2 () = Process1 ()
Wend
Delay (500)
Goto restart
(You can of course remove the userinit/"If windows_loaded" stuff if you don't need that.)