How to get Process Owner by Python using WMI?

2019-06-14 05:08发布

问题:

I tried to get some information about Process Owner, using WMI. I tried to run this script:

import win32com.client

process_wmi = set()
strComputer = "."
objWMIService = win32com.client.Dispatch("WbemScripting.SWbemLocator")
objSWbemServices = objWMIService.ConnectServer(strComputer,"root\cimv2")


process_list = objSWbemServices.ExecQuery("Select * from Win32_Process")
for process in process:
    owner = process.GetOwner
    if owner != 0:
        print('Access denied')
    else:
        print('process: ',process.Name, 'PID: ', process.ProcessId, 'Owner: ', owner)

Of course, i get owner = 0 (Successful Completion)

When I tried to call process.GetOwner(), I get this error: TypeError: 'int' object is not callable

How to use this method without errors? With what parameters or with what flags maybe?

I try to actualize and use this method, here, but I can't convert code to my situation and get Process Owner. =(

Or may be someone know another method, how to get information about process owner. May be with WinApi methods?

Thank you for help!

回答1:

I would suggest using the psutil library. I was using the winapi, and wmi, but it's terribly slow :( psutil is much, much faster and gives you a convenient API for working with processes.

You can achieve the same thing like this:

import psutil
for process in psutil.get_process_list():
    try:
        print('Process: %s, PID: %s, Owner: %s' % (process.name, process.pid,
                                                   process.username))
    except psutil.AccessDenied:
        print('Access denied!')

And because only the username can give you Access denied you can in except do:

except psutil.AccessDenied:
    print('Process: %s, PID: %s, Owner: DENIED' % (process.name, process.pid)

If you can use only pywin32 and wmi then this will work:

import wmi
for i in wmi.WMI().Win32_Process():
    print('%s, %s, %s' % (i.Name, i.ProcessId, i.GetOwner()[2]))


回答2:

The type error is because process_list from your code is an "unknown" COM object. Try this:

import win32com  
from win32com.client import GetObject  
wmi = win32com.client.GetObject("winmgmts:")  
wmi = win32com.client.gencache.EnsureDispatch(wmi._oleobj_)  
#Now execute your query  
process = wmi.ExecQuery('select * from Win32_Process')  
proc = process[0]  
#Now I can do things like check properties  
print proc.Properties_('ProcessId').Value  
#Or use methods  
parms = proc.ExecMethod_('GetOwner')  
#Now I can do things with parms like  
username = parms.Properties_('User').Value

Parms will be a com object of type SWbemObject just like process and proc are. It has other properties as well: return value and domain. I can poll it just like I did above for getting User from parms. Hope this helps.

Sorry, adding after the fact: the properties for parms in the code above specifically are User, Domain, and ReturnValue