Reference
utils_mystuff_windows ¶
Package with various utilities depending on windows platform i. e. windows handling
Set of submodules contains:
- submodule with utilities specific for Win32 platform
Raises:
| Type | Description |
|---|---|
ImportError | import error if implementation is not available for platform |
AssocQueryStringA = shlwapi.AssocQueryStringA module-attribute ¶
AssocQueryStringW = shlwapi.AssocQueryStringW module-attribute ¶
WM_CLOSE = 16 module-attribute ¶
shlwapi = ctypes.WinDLL('shlwapi', use_last_error=True) module-attribute ¶
ASSOCF ¶
IGNOREBASECLASS = 512 class-attribute instance-attribute ¶
INIT_BYEXENAME = 2 class-attribute instance-attribute ¶
INIT_DEFAULTTOFOLDER = 8 class-attribute instance-attribute ¶
INIT_DEFAULTTOSTAR = 4 class-attribute instance-attribute ¶
INIT_IGNOREUNKNOWN = 1024 class-attribute instance-attribute ¶
INIT_NOREMAPCLSID = 1 class-attribute instance-attribute ¶
NOFIXUPS = 256 class-attribute instance-attribute ¶
NONE = 0 class-attribute instance-attribute ¶
NOTRUNCATE = 32 class-attribute instance-attribute ¶
NOUSERSETTINGS = 16 class-attribute instance-attribute ¶
OPEN_BYEXENAME = 2 class-attribute instance-attribute ¶
REMAPRUNDLL = 128 class-attribute instance-attribute ¶
VERIFY = 64 class-attribute instance-attribute ¶
ASSOCSTR ¶
COMMAND = 1 class-attribute instance-attribute ¶
CONTENTTYPE = 14 class-attribute instance-attribute ¶
DDEAPPLICATION = 9 class-attribute instance-attribute ¶
DDECOMMAND = 7 class-attribute instance-attribute ¶
DDEIFEXEC = 8 class-attribute instance-attribute ¶
DDETOPIC = 10 class-attribute instance-attribute ¶
DEFAULTICON = 15 class-attribute instance-attribute ¶
EXECUTABLE = 2 class-attribute instance-attribute ¶
FRIENDLYAPPNAME = 4 class-attribute instance-attribute ¶
FRIENDLYDOCNAME = 3 class-attribute instance-attribute ¶
INFOTIP = 11 class-attribute instance-attribute ¶
NOOPEN = 5 class-attribute instance-attribute ¶
QUICKTIP = 12 class-attribute instance-attribute ¶
SHELLEXTENSION = 16 class-attribute instance-attribute ¶
SHELLNEWVALUE = 6 class-attribute instance-attribute ¶
TILEINFO = 13 class-attribute instance-attribute ¶
close_app_file(filename: str, msg: str, title: str, partial_allowed: bool = True, timeout: int = 5, kill_app: bool = True) -> None ¶
close_app_file - close data file opened by an application
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
filename | str | filename | required |
msg | str | message for alert box | required |
title | str | title for alert box | required |
partial_allowed | bool | partial matching of title allowed | True |
timeout | int | timeout for waiting after closing | 5 |
kill_app | bool | kill application locking file to be closed | True |
Source code in src\utils_mystuff_windows\utils_win32.py
def close_app_file(filename: str, msg: str, title: str, partial_allowed: bool = True, timeout: int = 5, kill_app: bool = True) -> None:
"""
close_app_file - close data file opened by an application
Args:
filename (str): filename
msg (str): message for alert box
title (str): title for alert box
partial_allowed (bool): partial matching of title allowed
timeout (int): timeout for waiting after closing
kill_app (bool): kill application locking file to be closed
"""
# first attempt: close by window title
if Utils.file_locked(filename):
close_app_windowtitle(filename, partial_allowed, timeout)
if Utils.file_locked(filename):
close_app_windowtitle(os.path.splitext(os.path.basename(filename))[0], partial_allowed, timeout)
# second attempt: kill respective process
if Utils.file_locked(filename):
executable = get_assoc_query(os.path.splitext(filename)[1])
for proc in psutil.process_iter(['exe']):
try:
if proc.info['exe'] and os.path.normcase(proc.info['exe']) == os.path.normcase(executable):
proc.kill()
proc.wait(timeout=5)
starttime = time.time()
while Utils.file_locked(filename) and time.time() < starttime + timeout:
time.sleep(0.1)
except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.TimeoutExpired):
pass
# third attempt:request to close manually
while Utils.file_locked(filename):
Utils.alertbox(msg, title)
close_app_windowtitle(title: str, partial_allowed: bool = True, timeout: int = 5) -> None ¶
close_app_windowtitle - close window / application depending on title
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title | str | window title | required |
partial_allowed | bool | partial matching of title allowed | True |
timeout | int | timeout for waiting after closing | 5 |
Source code in src\utils_mystuff_windows\utils_win32.py
def close_app_windowtitle(title: str, partial_allowed: bool = True, timeout: int = 5) -> None:
"""
close_app_windowtitle - close window / application depending on title
Args:
title (str): window title
partial_allowed (bool): partial matching of title allowed
timeout (int): timeout for waiting after closing
"""
close_app_windowtitle_win32gui(title, partial_allowed, timeout)
close_app_windowtitle_ctypes(title: str, partial_allowed: bool = True, timeout: int = 5) -> None ¶
close_app_windowtitle_ctypes - close window / application depending on title, variant using ctypes
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title | str | window title | required |
partial_allowed | bool | partial matching of title allowed | True |
timeout | int | timeout for waiting after closing | 5 |
Source code in src\utils_mystuff_windows\utils_win32.py
def close_app_windowtitle_ctypes(title: str, partial_allowed: bool = True, timeout: int = 5) -> None:
"""
close_app_windowtitle_ctypes - close window / application depending on title, variant using ctypes
Args:
title (str): window title
partial_allowed (bool): partial matching of title allowed
timeout (int): timeout for waiting after closing
"""
hwnd = find_window_ctypes(title, partial_allowed)
if hwnd:
ctypes.windll.user32.SendMessageA(hwnd, WM_CLOSE, 0, 0)
starttime = time.time()
while ctypes.windll.user32.IsWindow(hwnd) and time.time() < starttime + timeout:
time.sleep(0.1)
close_app_windowtitle_taskkill(title: str) -> None ¶
close_app_windowtitle_taskkill - close window / application depending on title, variant using taskkill
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title | str | window title | required |
Source code in src\utils_mystuff_windows\utils_win32.py
def close_app_windowtitle_taskkill(title: str) -> None:
"""
close_app_windowtitle_taskkill - close window / application depending on title, variant using taskkill
Args:
title (str): window title
"""
# os.system("taskkill /F /FI 'WINDOWTITLE eq {title}*'") # wildcard not allowed at beginning of title
os.system(f"for /f \"tokens=2 delims=,\" %a in ('tasklist /v /fo:csv /nh ^| findstr /r \"{title}\"') do taskkill /pid %a")
time.sleep(0.1)
close_app_windowtitle_win32gui(title: str, partial_allowed: bool = True, timeout: int = 5) -> None ¶
close_app_windowtitle_win32gui - close window / application depending on title, variant using win32gui
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title | str | window title | required |
partial_allowed | bool | partial matching of title allowed | True |
timeout | int | timeout for waiting after closing | 5 |
Source code in src\utils_mystuff_windows\utils_win32.py
def close_app_windowtitle_win32gui(title: str, partial_allowed: bool = True, timeout: int = 5) -> None:
"""
close_app_windowtitle_win32gui - close window / application depending on title, variant using win32gui
Args:
title (str): window title
partial_allowed (bool): partial matching of title allowed
timeout (int): timeout for waiting after closing
"""
hwnd = find_window_win32gui(title, partial_allowed)
if hwnd:
win32gui.SendMessage(hwnd, WM_CLOSE, 0, 0)
starttime = time.time()
while win32gui.IsWindow(hwnd) and time.time() < starttime + timeout:
time.sleep(0.1)
find_window_ctypes(title: str, partial_allowed: bool = True) -> Any ¶
find_window_ctypes - find windows from title, variant using ctypes
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title | str | window title | required |
partial_allowed | bool | partial matching of title allowed | True |
Returns:
| Type | Description |
|---|---|
Any | Union[str, bool]: title if found, False otherwise |
Source code in src\utils_mystuff_windows\utils_win32.py
def find_window_ctypes(title: str, partial_allowed: bool = True) -> Any:
"""
find_window_ctypes - find windows from title, variant using ctypes
Args:
title (str): window title
partial_allowed (bool): partial matching of title allowed
Returns:
Union[str, bool]: title if found, False otherwise
"""
titles = []
def foreach_window_gettitle(hwnd, lParam):
if ctypes.windll.user32.IsWindowVisible(hwnd):
length = ctypes.windll.user32.GetWindowTextLengthW(hwnd)
classname = ctypes.create_unicode_buffer(100 + 1)
ctypes.windll.user32.GetClassNameW(hwnd, classname, 100 + 1)
buff = ctypes.create_unicode_buffer(length + 1)
ctypes.windll.user32.GetWindowTextW(hwnd, buff, length + 1)
titles.append((hwnd, buff.value.encode(), classname.value, ctypes.windll.user32.IsIconic(hwnd)))
return True
def refresh_wins() -> Any:
titles: list[str] = []
ctypes.windll.user32.EnumWindows(ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.c_int, ctypes.POINTER(ctypes.c_int))(foreach_window_gettitle), 0)
refresh_wins()
# exact matching of title
for item in titles:
if title == str(item[1].decode()):
return item[0]
# partial matching of title
if partial_allowed:
for item in titles:
if title in str(item[1].decode()):
return item[0]
return False
find_window_win32gui(title: str, partial_allowed: bool = True) -> Any ¶
find_window_ctypes - find windows from title, variant using win32gui
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title | str | window title | required |
partial_allowed | bool | partial matching of title allowed | True |
Returns:
| Type | Description |
|---|---|
Any | Union[str, bool]: title if found, False otherwise |
Source code in src\utils_mystuff_windows\utils_win32.py
def find_window_win32gui(title: str, partial_allowed: bool = True) -> Any:
"""
find_window_ctypes - find windows from title, variant using win32gui
Args:
title (str): window title
partial_allowed (bool): partial matching of title allowed
Returns:
Union[str, bool]: title if found, False otherwise
"""
titles = []
def foreach_window_gettitle(hwnd, lParam):
if win32gui.IsWindowVisible(hwnd):
classname = win32gui.GetClassName(hwnd)
title = win32gui.GetWindowText(hwnd)
titles.append((hwnd, title, classname, win32gui.IsIconic(hwnd)))
return True
def refresh_wins():
titles = []
win32gui.EnumWindows(foreach_window_gettitle, 0)
refresh_wins()
# exact matching of title
for item in titles:
if title == str(item[1]):
return item[0]
# partial matching of title
if partial_allowed:
for item in titles:
if title in str(item[1]):
return item[0]
return False
get_assoc_query(extension: str, assoc_str: int = ASSOCSTR.EXECUTABLE.value) -> str ¶
get_assoc_query - read file extension association info via Win32API
file extension association info is read via Win32API call. Watch out for ANSI vs double byte version(s)! Since UTF-8 ist standard in Python, using the double byte version avoids some conversion stuff.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
extension | str | extension association info is looked for | required |
assoc_str | ASSOCSTR | association info index | EXECUTABLE.value |
Returns:
| Type | Description |
|---|---|
str | value |
Source code in src\utils_mystuff_windows\utils_win32.py
def get_assoc_query(extension: str, assoc_str: int = ASSOCSTR.EXECUTABLE.value) -> str:
"""
get_assoc_query - read file extension association info via Win32API
file extension association info is read via Win32API call.
Watch out for ANSI vs double byte version(s)! Since UTF-8 ist standard in Python,
using the double byte version avoids some conversion stuff.
Args:
extension (str): extension association info is looked for
assoc_str (ASSOCSTR): association info index
Returns:
value
"""
# Step 1: Determine buffer size
buffer_len = ctypes.wintypes.DWORD(0)
hr = AssocQueryStringA(ASSOCF.NONE.value, assoc_str, extension.encode('cp1252'), None, None, ctypes.byref(buffer_len))
# hr = AssocQueryStringW(ASSOCF.NONE.value, assoc_str, extension, None, None, ctypes.byref(buffer_len))
if buffer_len.value == 0:
return ""
# Step 2: Allocate buffer and retrieve the value
buffer = ctypes.create_string_buffer(buffer_len.value)
hr = AssocQueryStringA(ASSOCF.NONE.value, assoc_str, extension.encode('cp1252'), None, buffer, ctypes.byref(buffer_len))
result = buffer.value.decode()
# buffer = ctypes.create_unicode_buffer(buffer_len.value)
# hr = AssocQueryStringW(ASSOCF.NONE.value, assoc_str, extension, None, buffer, ctypes.byref(buffer_len))
# result = buffer.value
if hr != 0: # S_OK is 0
return ""
return result
wait_for_window(title: str, partial_allowed: bool = True, timeout: int = 5, wait: float = 0.25) -> None ¶
wait_for_window - wait for close window (overcome delay in asynchronous processing subprocess.Popen)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title | str | window title | required |
partial_allowed | bool | partial matching of title allowed | True |
timeout | int | timeout time. Defaults to 5. | 5 |
wait | float | wait time. Defaults to 0.25. | 0.25 |
Source code in src\utils_mystuff_windows\utils_win32.py
def wait_for_window(title: str, partial_allowed: bool = True, timeout: int = 5, wait: float = 0.25) -> None:
"""
wait_for_window - wait for close window (overcome delay in asynchronous processing subprocess.Popen)
Args:
title (str): window title
partial_allowed (bool): partial matching of title allowed
timeout (int, optional): timeout time. Defaults to 5.
wait (float, optional): wait time. Defaults to 0.25.
"""
wait_for_window_win32gui(title, partial_allowed, timeout, wait)
wait_for_window_ctypes(title: str, partial_allowed: bool = True, timeout: int = 5, wait: float = 0.25) -> None ¶
wait_for_window_ctypes - wait for close window (overcome delay in asynchronous processing subprocess.Popen)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title | str | window title | required |
partial_allowed | bool | partial matching of title allowed | True |
timeout | int | timeout time. Defaults to 5. | 5 |
wait | float | wait time. Defaults to 0.25. | 0.25 |
Source code in src\utils_mystuff_windows\utils_win32.py
def wait_for_window_ctypes(title: str, partial_allowed: bool = True, timeout: int = 5, wait: float = 0.25) -> None:
"""
wait_for_window_ctypes - wait for close window (overcome delay in asynchronous processing subprocess.Popen)
Args:
title (str): window title
partial_allowed (bool): partial matching of title allowed
timeout (int, optional): timeout time. Defaults to 5.
wait (float, optional): wait time. Defaults to 0.25.
"""
starttime = time.time()
while time.time() < starttime + timeout:
hwnd = find_window_ctypes(title, partial_allowed)
if hwnd:
return
else:
time.sleep(wait)
return
wait_for_window_win32gui(title: str, partial_allowed: bool = True, timeout: int = 5, wait: float = 0.25) -> None ¶
wait_for_window_win32gui - wait for close window (overcome delay in asynchronous processing subprocess.Popen)
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
title | str | window title | required |
partial_allowed | bool | partial matching of title allowed | True |
timeout | int | timeout time. Defaults to 5. | 5 |
wait | float | wait time. Defaults to 0.25. | 0.25 |
Source code in src\utils_mystuff_windows\utils_win32.py
def wait_for_window_win32gui(title: str, partial_allowed: bool = True, timeout: int = 5, wait: float = 0.25) -> None:
"""
wait_for_window_win32gui - wait for close window (overcome delay in asynchronous processing subprocess.Popen)
Args:
title (str): window title
partial_allowed (bool): partial matching of title allowed
timeout (int, optional): timeout time. Defaults to 5.
wait (float, optional): wait time. Defaults to 0.25.
"""
starttime = time.time()
while time.time() < starttime + timeout:
hwnd = find_window_win32gui(title, partial_allowed)
if hwnd:
return
else:
time.sleep(wait)
return