From 569ce30b9672c77e6d553a03098160c0c13e166c Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Wed, 6 Nov 2024 11:38:44 +0100 Subject: [PATCH 1/4] pass all required arguments to FileDefItem --- client/ayon_core/lib/attribute_definitions.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/client/ayon_core/lib/attribute_definitions.py b/client/ayon_core/lib/attribute_definitions.py index 34956fd33f..789c878d40 100644 --- a/client/ayon_core/lib/attribute_definitions.py +++ b/client/ayon_core/lib/attribute_definitions.py @@ -966,7 +966,9 @@ class FileDef(AbstractAttrDef): FileDefItem.from_dict(default) elif isinstance(default, str): - default = FileDefItem.from_paths([default.strip()])[0] + default = FileDefItem.from_paths( + [default.strip()], allow_sequences + )[0] else: raise TypeError(( @@ -1044,7 +1046,9 @@ class FileDef(AbstractAttrDef): pass if string_paths: - file_items = FileDefItem.from_paths(string_paths) + file_items = FileDefItem.from_paths( + string_paths, self.allow_sequences + ) dict_items.extend([ file_item.to_dict() for file_item in file_items From 749984c0bff74c4491a7d6e853afa70906b1e984 Mon Sep 17 00:00:00 2001 From: Roy Nieterau Date: Fri, 8 Nov 2024 13:10:44 +0100 Subject: [PATCH 2/4] Fix loader load option box widgets --- client/ayon_core/tools/attribute_defs/widgets.py | 1 - 1 file changed, 1 deletion(-) diff --git a/client/ayon_core/tools/attribute_defs/widgets.py b/client/ayon_core/tools/attribute_defs/widgets.py index 22f4bfe535..93f63730f5 100644 --- a/client/ayon_core/tools/attribute_defs/widgets.py +++ b/client/ayon_core/tools/attribute_defs/widgets.py @@ -202,7 +202,6 @@ class AttributeDefinitionsWidget(QtWidgets.QWidget): self._current_keys.add(attr_def.key) widget = create_widget_for_attr_def(attr_def, self) - self._widgets.append(widget) self._widgets_by_id[attr_def.id] = widget if not attr_def.visible: From 20206a3cf3444c3a74b8f3aa046985def1cbfa38 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Fri, 8 Nov 2024 16:57:00 +0100 Subject: [PATCH 3/4] check executable name before killing the process --- client/ayon_core/tools/tray/lib.py | 103 ++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 11 deletions(-) diff --git a/client/ayon_core/tools/tray/lib.py b/client/ayon_core/tools/tray/lib.py index 39fcc2cdd3..94550775e6 100644 --- a/client/ayon_core/tools/tray/lib.py +++ b/client/ayon_core/tools/tray/lib.py @@ -3,12 +3,9 @@ import sys import json import hashlib import platform -import subprocess -import csv import time import signal -import locale -from typing import Optional, Dict, Tuple, Any +from typing import Optional, List, Dict, Tuple, Any import requests from ayon_api.utils import get_default_settings_variant @@ -53,15 +50,99 @@ def _get_server_and_variant( return server_url, variant +def _windows_get_pid_args(pid: int) -> Optional[List[str]]: + import ctypes + from ctypes import wintypes + + # Define constants + PROCESS_COMMANDLINE_INFO = 60 + STATUS_NOT_FOUND = 0xC0000225 + PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 + + # Define the UNICODE_STRING structure + class UNICODE_STRING(ctypes.Structure): + _fields_ = [ + ("Length", wintypes.USHORT), + ("MaximumLength", wintypes.USHORT), + ("Buffer", wintypes.LPWSTR) + ] + + shell32 = ctypes.WinDLL("shell32", use_last_error=True) + + CommandLineToArgvW = shell32.CommandLineToArgvW + CommandLineToArgvW.argtypes = [ + wintypes.LPCWSTR, ctypes.POINTER(ctypes.c_int) + ] + CommandLineToArgvW.restype = ctypes.POINTER(wintypes.LPWSTR) + + output = None + # Open the process + handle = ctypes.windll.kernel32.OpenProcess( + PROCESS_QUERY_LIMITED_INFORMATION, False, pid + ) + if not handle: + return output + + try: + buffer_len = wintypes.ULONG() + # Get the right buffer size first + status = ctypes.windll.ntdll.NtQueryInformationProcess( + handle, + PROCESS_COMMANDLINE_INFO, + ctypes.c_void_p(None), + 0, + ctypes.byref(buffer_len) + ) + + if status == STATUS_NOT_FOUND: + return output + + # Create buffer with collected size + buffer = ctypes.create_string_buffer(buffer_len.value) + + # Get the command line + status = ctypes.windll.ntdll.NtQueryInformationProcess( + handle, + PROCESS_COMMANDLINE_INFO, + buffer, + buffer_len, + ctypes.byref(buffer_len) + ) + if status: + return output + # Build the string + tmp = ctypes.cast(buffer, ctypes.POINTER(UNICODE_STRING)).contents + size = tmp.Length // 2 + 1 + cmdline_buffer = ctypes.create_unicode_buffer(size) + ctypes.cdll.msvcrt.wcscpy(cmdline_buffer, tmp.Buffer) + + args_len = ctypes.c_int() + args = CommandLineToArgvW( + cmdline_buffer, ctypes.byref(args_len) + ) + output = [args[idx] for idx in range(args_len.value)] + ctypes.windll.kernel32.LocalFree(args) + + finally: + ctypes.windll.kernel32.CloseHandle(handle) + return output def _windows_pid_is_running(pid: int) -> bool: - args = ["tasklist.exe", "/fo", "csv", "/fi", f"PID eq {pid}"] - output = subprocess.check_output(args) - encoding = locale.getpreferredencoding() - csv_content = csv.DictReader(output.decode(encoding).splitlines()) - # if "PID" not in csv_content.fieldnames: - # return False - for _ in csv_content: + args = _windows_get_pid_args(pid) + if not args: + return False + executable_path = args[0] + + filename = os.path.basename(executable_path).lower() + if "ayon" in filename: return True + + # Try to handle tray running from code + # - this might be potential danger that kills other python process running + # 'start.py' script (low chance, but still) + if "python" in filename and len(args) > 1: + script_filename = os.path.basename(args[1].lower()) + if script_filename == "start.py": + return True return False From 41db386f23f4ec18e870abe1817d0f71eb8fc775 Mon Sep 17 00:00:00 2001 From: Jakub Trllo <43494761+iLLiCiTiT@users.noreply.github.com> Date: Fri, 8 Nov 2024 16:59:05 +0100 Subject: [PATCH 4/4] add empty lines --- client/ayon_core/tools/tray/lib.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/ayon_core/tools/tray/lib.py b/client/ayon_core/tools/tray/lib.py index 94550775e6..13ee1eea5c 100644 --- a/client/ayon_core/tools/tray/lib.py +++ b/client/ayon_core/tools/tray/lib.py @@ -126,6 +126,8 @@ def _windows_get_pid_args(pid: int) -> Optional[List[str]]: finally: ctypes.windll.kernel32.CloseHandle(handle) return output + + def _windows_pid_is_running(pid: int) -> bool: args = _windows_get_pid_args(pid) if not args: