pyappify 1.0.3__tar.gz → 1.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyappify-1.0.3 → pyappify-1.0.4}/PKG-INFO +1 -1
- {pyappify-1.0.3 → pyappify-1.0.4}/pyappify/__init__.py +59 -1
- {pyappify-1.0.3 → pyappify-1.0.4}/pyappify.egg-info/PKG-INFO +1 -1
- {pyappify-1.0.3 → pyappify-1.0.4}/pyproject.toml +1 -1
- {pyappify-1.0.3 → pyappify-1.0.4}/pyappify/main.py +0 -0
- {pyappify-1.0.3 → pyappify-1.0.4}/pyappify.egg-info/SOURCES.txt +0 -0
- {pyappify-1.0.3 → pyappify-1.0.4}/pyappify.egg-info/dependency_links.txt +0 -0
- {pyappify-1.0.3 → pyappify-1.0.4}/pyappify.egg-info/entry_points.txt +0 -0
- {pyappify-1.0.3 → pyappify-1.0.4}/pyappify.egg-info/requires.txt +0 -0
- {pyappify-1.0.3 → pyappify-1.0.4}/pyappify.egg-info/top_level.txt +0 -0
- {pyappify-1.0.3 → pyappify-1.0.4}/setup.cfg +0 -0
- {pyappify-1.0.3 → pyappify-1.0.4}/tests/TestUpdateEnv.py +0 -0
- {pyappify-1.0.3 → pyappify-1.0.4}/tests/TestUpgrade.py +0 -0
- {pyappify-1.0.3 → pyappify-1.0.4}/tests/TestUpgradeOnline.py +0 -0
- {pyappify-1.0.3 → pyappify-1.0.4}/tests/TestVersion.py +0 -0
|
@@ -8,6 +8,7 @@ import shutil
|
|
|
8
8
|
import urllib.request
|
|
9
9
|
import zipfile
|
|
10
10
|
import threading
|
|
11
|
+
import time
|
|
11
12
|
|
|
12
13
|
app_version = os.environ.get("PYAPPIFY_APP_VERSION")
|
|
13
14
|
app_starting_version = os.environ.get("PYAPPIFY_APP_STARTING_VERSION") or app_version
|
|
@@ -78,10 +79,67 @@ def kill_pyappify():
|
|
|
78
79
|
log.info(f"Attempting to terminate process with PID: {pid}")
|
|
79
80
|
try:
|
|
80
81
|
os.kill(pid, signal.SIGTERM)
|
|
82
|
+
if not _wait_for_process_exit(pid):
|
|
83
|
+
log.warning(f"Timed out waiting for process with PID {pid} to exit.")
|
|
81
84
|
except Exception as e:
|
|
82
85
|
log.error(f"Failed to terminate process with PID {pid}: {e}")
|
|
83
86
|
pass
|
|
84
87
|
|
|
88
|
+
|
|
89
|
+
def _wait_for_process_exit(process_pid, timeout=30):
|
|
90
|
+
if sys.platform == "win32" and ctypes:
|
|
91
|
+
synchronize = 0x00100000
|
|
92
|
+
wait_timeout = 0x00000102
|
|
93
|
+
wait_failed = 0xFFFFFFFF
|
|
94
|
+
ctypes.windll.kernel32.OpenProcess.argtypes = (
|
|
95
|
+
ctypes.c_uint,
|
|
96
|
+
ctypes.c_bool,
|
|
97
|
+
ctypes.c_ulong,
|
|
98
|
+
)
|
|
99
|
+
ctypes.windll.kernel32.OpenProcess.restype = ctypes.c_void_p
|
|
100
|
+
ctypes.windll.kernel32.WaitForSingleObject.argtypes = (
|
|
101
|
+
ctypes.c_void_p,
|
|
102
|
+
ctypes.c_uint,
|
|
103
|
+
)
|
|
104
|
+
ctypes.windll.kernel32.WaitForSingleObject.restype = ctypes.c_uint
|
|
105
|
+
ctypes.windll.kernel32.CloseHandle.argtypes = (ctypes.c_void_p,)
|
|
106
|
+
ctypes.windll.kernel32.CloseHandle.restype = ctypes.c_bool
|
|
107
|
+
handle = ctypes.windll.kernel32.OpenProcess(synchronize, False, process_pid)
|
|
108
|
+
if handle:
|
|
109
|
+
try:
|
|
110
|
+
result = ctypes.windll.kernel32.WaitForSingleObject(
|
|
111
|
+
handle, int(timeout * 1000)
|
|
112
|
+
)
|
|
113
|
+
if result == wait_failed:
|
|
114
|
+
return False
|
|
115
|
+
return result != wait_timeout
|
|
116
|
+
finally:
|
|
117
|
+
ctypes.windll.kernel32.CloseHandle(handle)
|
|
118
|
+
|
|
119
|
+
deadline = time.monotonic() + timeout
|
|
120
|
+
while time.monotonic() < deadline:
|
|
121
|
+
try:
|
|
122
|
+
os.kill(process_pid, 0)
|
|
123
|
+
except OSError:
|
|
124
|
+
return True
|
|
125
|
+
time.sleep(0.1)
|
|
126
|
+
return False
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
def _replace_executable(source_path, target_path, timeout=30):
|
|
130
|
+
deadline = time.monotonic() + timeout
|
|
131
|
+
last_error = None
|
|
132
|
+
while True:
|
|
133
|
+
try:
|
|
134
|
+
shutil.move(source_path, target_path)
|
|
135
|
+
return
|
|
136
|
+
except PermissionError as e:
|
|
137
|
+
last_error = e
|
|
138
|
+
if time.monotonic() >= deadline:
|
|
139
|
+
raise last_error
|
|
140
|
+
time.sleep(0.25)
|
|
141
|
+
|
|
142
|
+
|
|
85
143
|
def hide_pyappify():
|
|
86
144
|
if pid:
|
|
87
145
|
log = _get_logger()
|
|
@@ -154,7 +212,7 @@ def upgrade(to_version, executable_sha256, executable_zip_urls, stop_event=None)
|
|
|
154
212
|
return
|
|
155
213
|
|
|
156
214
|
kill_pyappify()
|
|
157
|
-
|
|
215
|
+
_replace_executable(found_executable_path, pyappify_executable)
|
|
158
216
|
log.info(f"pyappify Upgrade success")
|
|
159
217
|
except Exception as e:
|
|
160
218
|
log.error(f"pyappify Upgrade failed: {e}")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|