Before everything, I want to point out [SO]: C function called from Python via ctypes returns incorrect value (@CristiFati's answer). Read it before working with CTypes.
Here's what I meant in the comment:
import win32gui
def enumWindowsProc(hwnd, lParam):
print win32gui.GetWindowText(hwnd)
win32gui.EnumWindows(enumWindowsProc, 0)
Below, I pasted the whole thing...it doesn't work on the PC that I am at right now, since I messed up with security settings (it's an XP!!!) and I get a bunch of Access denied (error code: 5) errors, but here it is.
code00.py:
#!/usr/bin/env python3
import sys
import os
import traceback
import ctypes
from ctypes import wintypes
import win32con
import win32api
import win32gui
import win32process
def enumWindowsProc(hwnd, lParam):
if (lParam is None) or ((lParam is not None) and (win32process.GetWindowThreadProcessId(hwnd)[1] == lParam)):
text = win32gui.GetWindowText(hwnd)
if text:
wStyle = win32api.GetWindowLong(hwnd, win32con.GWL_STYLE)
if wStyle & win32con.WS_VISIBLE:
print("%08X - %s" % (hwnd, text))
def enumProcWnds(pid=None):
win32gui.EnumWindows(enumWindowsProc, pid)
def enumProcs(procName=None):
pids = win32process.EnumProcesses()
if procName is not None:
bufLen = 0x100
_OpenProcess = ctypes.windll.kernel32.OpenProcess
_OpenProcess.argtypes = [wintypes.DWORD, wintypes.BOOL, wintypes.DWORD]
_OpenProcess.restype = wintypes.HANDLE
_GetProcessImageFileName = ctypes.windll.psapi.GetProcessImageFileNameA
_GetProcessImageFileName.argtypes = [wintypes.HANDLE, wintypes.LPSTR, wintypes.DWORD]
_GetProcessImageFileName.restype = wintypes.DWORD
_CloseHandle = ctypes.windll.kernel32.CloseHandle
_CloseHandle.argtypes = [wintypes.HANDLE]
_CloseHandle.restype = wintypes.BOOL
filteredPids = ()
for pid in pids:
try:
hProc = _OpenProcess(win32con.PROCESS_ALL_ACCESS, 0, pid)
except:
print("Process [%d] couldn't be opened: %s" % (pid, traceback.format_exc()))
continue
try:
buf = ctypes.create_string_buffer(bufLen)
_GetProcessImageFileName(hProc, buf, bufLen)
if buf.value:
name = buf.value.decode().split(os.path.sep)[-1]
#print name
else:
_CloseHandle(hProc)
continue
except:
print("Error getting process name: %s" % traceback.format_exc())
_CloseHandle(hProc)
continue
if name.lower() == procName.lower():
filteredPids += (pid,)
_CloseHandle(hproc)
return filteredPids
else:
return pids
def main(args):
if args:
procName = args[0]
else:
procName = None
pids = enumProcs(procName)
#print(pids)
for pid in pids:
enumProcWnds(pid)
if __name__ == "__main__":
print("Python {:s} on {:s}
".format(sys.version, sys.platform))
main(sys.argv[1:])
Needless to say that:
- In order for this code to work, you need to run it as a privileged user (Administrator); at least SeDebugPrivilege ([MS.Docs]: Privilege Constants) is required.
- There might be surprises when the processes are running in 32 / 64 bit modes (the python process that you execute this code from, and the target processes enumerated by the code)
Update #0
- Replaced all CTypes calls by PyWin32 ones
- Improved algorithm
- Fixed error in previous version
code01.py:
#!/usr/bin/env python3
import sys
import os
import traceback
import win32con as wcon
import win32api as wapi
import win32gui as wgui
import win32process as wproc
# Callback
def enum_windows_proc(wnd, param):
pid = param.get("pid", None)
data = param.get("data", None)
if pid is None or wproc.GetWindowThreadProcessId(wnd)[1] == pid:
text = wgui.GetWindowText(wnd)
if text:
style = wapi.GetWindowLong(wnd, wcon.GWL_STYLE)
if style & wcon.WS_VISIBLE:
if data is not None:
data.append((wnd, text))
#else:
#print("%08X - %s" % (wnd, text))
def enum_process_windows(pid=None):
data = []
param = {
"pid": pid,
"data": data,
}
wgui.EnumWindows(enum_windows_proc, param)
return data
def _filter_processes(processes, search_name=None):
if search_name is None:
return processes
filtered = []
for pid, _ in processes:
try:
proc = wapi.OpenProcess(wcon.PROCESS_ALL_ACCESS, 0, pid)
except:
#print("Process {0:d} couldn't be opened: {1:}".format(pid, traceback.format_exc()))
continue
try:
file_name = wproc.GetModuleFileNameEx(proc, None)
except:
#print("Error getting process name: {0:}".format(traceback.format_exc()))
wapi.CloseHandle(proc)
continue
base_name = file_name.split(os.path.sep)[-1]
if base_name.lower() == search_name.lower():
filtered.append((pid, file_name))
wapi.CloseHandle(proc)
return tuple(filtered)
def enum_processes(process_name=None):
procs = [(pid, None) for pid in wproc.EnumProcesses()]
return _filter_processes(procs, search_name=process_name)
def main(*args):
proc_name = args[0] if args else None
procs = enum_processes(process_name=proc_name)
for pid, name in procs:
data = enum_process_windows(pid)
if data:
proc_text = "PId {0:d}{1:s}windows:".format(pid, " (File: [{0:s}]) ".format(name) if name else " ")
print(proc_text)
for handle, text in data:
print(" {0:d}: [{1:s}]".format(handle, text))
if __name__ == "__main__":
print("Python {0:s} {1:d}bit on {2:s}
".format(" ".join(item.strip() for item in sys.version.split("
")), 64 if sys.maxsize > 0x100000000 else 32, sys.platform))
main(*sys.argv[1:])
print("
Done.")
Output:
[cfati@CFATI-5510-0:e:WorkDevStackOverflowq031278590]> "e:WorkDevVEnvspy_pc064_03.07.06_test0Scriptspython.exe" code01.py
Python 3.7.6 (tags/v3.7.6:43364a7ae0, Dec 19 2019, 00:42:30) [MSC v.1916 64 bit (AMD64)] 64bit on win32
PId 8048 windows:
131462: [Program Manager]
PId 10292 windows:
133738: [Skype]
PId 5716 windows:
89659824: [python - Get the title of a window of another program using the process name - Stack Overflow - Google Chrome]
132978: [Service Name and Transport Protocol Port Number Registry - Google Chrome]
329646: [CristiFati/Prebuilt-Binaries: Various software built on various platforms. - Google Chrome]
133078: [unittest — Unit testing framework — Python 3.8.2 documentation - Google Chrome]
263924: [libssh2/libssh2 at libssh2-1.9.0 - Google Chrome]
264100: [WNetAddConnection2A function (winnetwk.h) - Win32 apps | Microsoft Docs - Google Chrome]
525390: [Understanding 4D -- The Tesseract - YouTube - Google Chrome]
198398: [Workaround for virtual environments (VirtualEnv) by CristiFati · Pull Request #1442 · mhammond/pywin32 - Google Chrome]
591586: [struct — Interpret bytes as packed binary data — Python 3.8.2 documentation - Google Chrome]
263982: [Simulating an epidemic - YouTube - Google Chrome]
329312: [SetHandleInformation function (handleapi.h) - Win32 apps | Microsoft Docs - Google Chrome]
263248: [studiu functie faze - Google Search - Google Chrome]
198364: [Lambda expressions (since C++11) - cppreference.com - Google Chrome]
PId 13640 windows:
984686: [Total Commander (x64) 9.22a - NOT REGISTERED]
44046462: [Lister - [c:cpula.txt]]
4135542: [Lister - [e:WorkDevCristiFatiBuildsWinOPSWpython27srcpywin32-b222win32srcwin32process.i]]
3873800: [Lister - [e:WorkDevCristiFatiBuildsWinOPSWpython27srcpywin32-b222win32srcPyHANDLE.cpp]]
29825332: [Lister - [E:WorkDevProjectsDevTelifmyosemiteGitLabAyoseissuesuildnrdependencies_200412.json]]
8329240: [Lister - [e:WorkDevProjectsDevTelifmyosemitesrcsvnyosemiteCFATI_TRUNK_2src
esicpVerAppX.h]]
985026: [Lister - [e:WorkDevCristiFatiBuildsWinOPSWpython27srcpywin32-b222win32srcwin32apimodule.cpp]]
PId 10936 windows:
264744: [Junk - [email protected] - Mozilla Thunderbird]
PId 10848 windows:
1115842: [Registry Editor]
PId 6164 windows:
264756: [Rocket.Chat]
PId 2716 windows:
854508: [Skype]
199310: [New tab and 5 more pages ?- Microsoft Edge]
PId 14936 windows:
655466: [Administrator: C:WindowsSystem32cmd.exe]
PId 15132 windows:
526852: [Administrator: Cmd (064) - "e:WorkDevVEnvspy_pc064_03.07.06_test0Scriptspython.exe"]
PId 15232 windows:
133918: [Microsoft Edge]
PId 9748 windows:
68492: [Microsoft Edge]
PId 14968 windows:
134146: [Microsoft Edge]
68634: [Microsoft Edge]
PId 15636 windows:
134208: [Microsoft Edge]
PId 16348 windows:
1379450: [Microsoft Edge]
PId 15568 windows:
68828: [Microsoft Edge]
68788: [Microsoft Edge]
PId 16040 windows:
265406: [Administrator: Cmd (032)]
PId 5792 windows:
2034532: [e:WorkDevStackOverflowq031278590code00.py - Notepad++ [Administrator]]
PId 12032 windows:
69134: [Microsoft Edge]
PId 16200 windows:
69146: [Microsoft Text Input Application]
PId 16224 windows:
69184: [Microsoft Edge]
PId 5288 windows:
265806: [Administrator: Cmd (064) - "e:WorkDevVEnvspy_pc032_03.07.06_test0Scriptspython.exe"]
PId 16476 windows:
265814: [Administrator: Cmd (064) - "e:WorkDevVEnvspy_pc064_03.08.01_test0Scriptspython.exe"]
PId 16612 windows:
331388: [Administrator: Cmd (064) - python]
PId 16796 windows:
592540: [Administrator: Cmd (064)]
PId 16880 windows:
264894: [Administrator: C:WindowsSystem32cmd.exe]
PId 17156 windows:
69284: [Console1 - Microsoft Visual Studio (Administrator)]
PId 16636 windows:
69396: [QtConsole0 - Microsoft Visual Studio (Administrator)]
PId 18380 windows:
69522: [Console0 - Microsoft Visual Studio (Administrator)]
PId 18108 windows:
200528: [BlackBird - Microsoft Visual Studio (Administrator)]
PId 19476 windows:
1052868: [pcbuild - Microsoft Visual Studio (Administrator)]
PId 16680 windows:
200924: [Yosemite - Microsoft Visual Studio (Administrator)]
PId 16020 windows:
201030: [-bash]
PId 6532 windows:
200996: [-bash]
PId 13140 windows:
266602: [-bash]
PId 6032 windows:
790834: [-bash]
PId 8496 windows:
8130950: [-bash]
PId 3208 windows:
4198878: [-bash]
PId 19088 windows:
528856: [-bash]
PId 12744 windows:
266770: [-bash]
PId 3896 windows:
201370: [-bash]
PId 11512 windows:
1315422: [Yosemite - Microsoft Visual Studio (Adm