"Valdas Bucinskas" valdas.bucinskas@ipsistemos.lt wrote:
Hello,
Wow, your examples are really interesting and helps incredibly much. I modified your your last example slightly, incorporating RAMs used by the process. And then tried to find the .exe that calls the process. It appears, the method GetModuleBaseName from psapi.dll should be used, which is described in
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/bas
e/getmodulebasename.asp. It gives the method declaration is DWORD GetModuleBaseName( HANDLE hProcess, HMODULE hModule, LPTSTR lpBaseName, DWORD nSize ); What I miss now is the knowledge, how do I convert types from c++ like into Sueak ones. I guess hProcess corresponds to Win32Handle, lpBaseName corresponds to char*, and nSize corresponds to long. GetModuleBaseName returns long.
- But what does hModule correspond to?
My guess <apicall: long 'GetModuleBaseName' (Win32Handle Win32Handle char* long) module: 'psapi.dll'>
almost correct, but the name of the function is 'GetModuleBaseNameA' where the last character stands for ASCII. A DLL contents viewer helps a lot to find out such details, I use this one: http://www.nirsoft.net/utils/dll_export_viewer.html
throughs Error 13, which is 'The data is invalid.' 2. Should a class similar to Win32Handle be created in order to hModule typecasting work?
No, that is not needed, hModule is a handle, Win32Handle is the right choice.
No please try this:
1. add this api method to Win32Window:
apiGetModuleBaseName: hProcess module: hModule into: lpString bufferSize: size <apicall: long 'GetModuleBaseNameA' (Win32Handle Win32Handle char* long) module: 'psapi.dll'> ^self externalCallFailed
2. Ensure that you open the process handle with access rights 16r410 (this is PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, the access right alone PROCESS_QUERY_INFORMATION does not allow you tho read the name) (The processes System, Idle and some others will not tell you their names anyway)
3. Do something like this:
handleArray do: [:idx | processHandle := interface getProcessHandleWithAccessRights: 16r410 inherit: true processId: idx. processHandle notNil ifTrue: [ | buffer processName cnt | buffer := ByteArray new: 80. interface apiGetModuleBaseName: processHandle module: nil into: buffer bufferSize: 80. processName := WriteStream on: (String new: 80). cnt := 1. [i <= 80 and: [(buffer at: cnt) ~= 0]] whileTrue: [processName nextPut: (Character value: (buffer at: cnt)). cnt := cnt + 1]. processName := processName contents. oc add: (Array with: idx with: (interface apiGetGuiResources: processHandle type: 0) with: (interface apiGetGuiResources: processHandle type: 1) with: processName).
interface closeHandle: processHandle. ] ].
When you have to provide buffers that are filled with some information, it is always a good choice to use ByteArrays of suitable size. You can always convert a ByteArray into a number or into a string.
Hope this helps, Boris