AudioControl/get_app_name.py
2022-11-06 22:23:39 +03:00

59 lines
1.9 KiB
Python

import ctypes
from ctypes import wintypes as w
import array
from functools import lru_cache
from psutil import Process
import traceback
ver = ctypes.WinDLL('version')
ver.GetFileVersionInfoSizeW.argtypes = w.LPCWSTR, w.LPDWORD
ver.GetFileVersionInfoSizeW.restype = w.DWORD
ver.GetFileVersionInfoW.argtypes = w.LPCWSTR, w.DWORD, w.DWORD, w.LPVOID
ver.GetFileVersionInfoW.restype = w.BOOL
ver.VerQueryValueW.argtypes = w.LPCVOID, w.LPCWSTR, ctypes.POINTER(w.LPVOID), w.PUINT
ver.VerQueryValueW.restype = w.BOOL
def get_file_description(filepath: str) -> str:
# https://stackoverflow.com/questions/42604493/verqueryvaluew-issue-python-3
size = ver.GetFileVersionInfoSizeW(filepath, None)
if not size:
raise RuntimeError('version info not found')
res = ctypes.create_string_buffer(size)
if not ver.GetFileVersionInfoW(filepath, 0, size, res):
raise RuntimeError('GetFileVersionInfoW failed')
buf = w.LPVOID()
length = w.UINT()
# Look for codepages
if not ver.VerQueryValueW(res, r'\VarFileInfo\Translation', ctypes.byref(buf), ctypes.byref(length)):
raise RuntimeError('VerQueryValueW failed to find translation')
if length.value == 0:
raise RuntimeError('no code pages')
codepages = array.array('H', ctypes.string_at(buf.value, length.value))
codepage = codepages[:2]
# Extract information
if not ver.VerQueryValueW(
res,
rf'\StringFileInfo\{codepage[0]:04x}{codepage[1]:04x}\FileDescription',
ctypes.byref(buf),
ctypes.byref(length)
):
raise RuntimeError('VerQueryValueW failed to find file version')
return ctypes.wstring_at(buf.value, length.value - 1)
@lru_cache
def get_app_name(app_process: Process) -> str:
try:
return get_file_description(app_process.exe())
except Exception:
traceback.print_exc()
return app_process.name()