How to get all running processes in VASmalltalk …

This has been asked in the Instantiations forum and that was pretty interesting and I ended up with a quick and dirty solution:

"
	Smalltalk equivalent to http://support.microsoft.com/kb/187913/en-us/
"
| ModuleNameAPI ptrToArrayProcessIDs ptrToString cbNeeded2 ptrToArrayModules EnumProcessesModulesAPI arrayProcessIDsSize ptrToBytesReturned EnumProcessesAPI numberOfProcesses |

EnumProcessesAPI := MSKExternalLibraryInterface
                                    createPlatformFunction: #('EnumProcesses' nil (pointer int32 pointer) boolean
                                    libraryName: 'psapi.dll'.

EnumProcessesModulesAPI := MSKExternalLibraryInterface
                                   createPlatformFunction: #('EnumProcessModules' nil (int32 pointer int32 pointer) boolean)
                                   libraryName: 'psapi.dll'.

ModuleNameAPI := MSKExternalLibraryInterface
                                  createPlatformFunction: #('GetModuleFileNameExA' nil (int32 int32 pointer int32) int32)
                                  libraryName: 'psapi.dll'.

arrayProcessIDsSize := 500.
ptrToArrayProcessIDs := OSInt32 new: arrayProcessIDsSize.
ptrToArrayModules := OSInt32 new: arrayProcessIDsSize.
ptrToBytesReturned := OSInt32 new: 1.
cbNeeded2 := OSInt32 new: 1.

EnumProcessesAPI callWith: ptrToArrayProcessIDs with: arrayProcessIDsSize with: ptrToBytesReturned.
Transcript cr ; show: 'Number of Bytes returned ...', (ptrToBytesReturned int32At:  0) printString.
numberOfProcesses := (ptrToBytesReturned int32At:  0) / 4.
Transcript cr ; show: 'Number of processes returned ...',  numberOfProcesses printString.

0 to: numberOfProcesses - 1 do: [ :eachIndex |
	| singleProcessID processHandle |

	singleProcessID := ptrToArrayProcessIDs uint32At: (eachIndex *   4).
	"Transcript cr ; show: 'Process with ID = ', singleProcessID printString,' inspected'."
	"PROCESS_QUERY_INFORMATION | PROCESS_VM_READ"
	processHandle := PlatformFunctions::OpenProcess callWith: (1024 + 16) with: false with: singleProcessID.
	processHandle ~= 0 ifTrue:[
			ptrToString := OSStringZ new: 500.
			((ModuleNameAPI callWith: processHandle with: nil with: ptrToString with: 500) > 0) ifTrue:[
				Transcript cr ; show: 'path of executable with processID (',singleProcessID printString,'): ',ptrToString asString.
			].
			PlatformFunctions::CloseHandle callWith: processHandle.
			"Transcript cr ; show: 'Process with ID = ', singleProcessID printString,' inspection closed'."
	]
	ifFalse:[
	]
]

in addition to the helper function:

createPlatformFunction: anArray libraryName: libraryName

	| newArray |

	newArray := Array new: 6.
	newArray
		at: 1 put: self libraryCallingConvention ;
		at: 2 put: (self apiNamePrefix,(anArray at: 1)) ;
		at: 3 put: (anArray at: 2);
		at: 4 put: libraryName;
		at: 5 put: (anArray at: 3) ;
		at: 6 put: (anArray at: 4).

	^PlatformFunction fromArray: newArray
This entry was posted in Smalltalk. Bookmark the permalink.