Skip to content

Commit 1f2ce51

Browse files
committed
relaunch after PYAPP self-update from win explorer
1 parent a23169b commit 1f2ce51

2 files changed

Lines changed: 45 additions & 9 deletions

File tree

src/redfetch/main.py

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,19 @@ class Env(str, Enum):
3939
EMU = "EMU"
4040

4141

42+
def should_relaunch_after_pyapp_update() -> bool:
43+
"""Relaunch after a PYAPP self-update only for double-click/Explorer launches."""
44+
if sys.platform != "win32" or not os.getenv("PYAPP"):
45+
return False
46+
try:
47+
import psutil # type: ignore
48+
49+
parent = psutil.Process().parent()
50+
return bool(parent and parent.name().lower() == "explorer.exe")
51+
except Exception:
52+
return False
53+
54+
4255
def parse_resource_id_or_fail(value: str) -> str:
4356
"""Accept either an integer ID or a URL that includes a recognizable ID."""
4457
value_stripped = value.strip()
@@ -274,7 +287,7 @@ def run_tui():
274287
# Initialize config early; terminal_ui accesses config at import time
275288
config.initialize_config()
276289
if os.environ.get('CI') != 'true':
277-
_ = meta.check_for_update()
290+
_ = meta.check_for_update(relaunch=should_relaunch_after_pyapp_update())
278291
# Ensure the user is authorized before launching UI
279292
auth.initialize_keyring()
280293
auth.authorize()

src/redfetch/meta.py

Lines changed: 31 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import subprocess
55
import sys
66
import textwrap
7+
import tempfile
78
from pathlib import Path
89

910
# Third-party
@@ -166,7 +167,7 @@ def get_update_command():
166167
return commands.get(method)
167168

168169

169-
def check_for_update():
170+
def check_for_update(relaunch: bool = False):
170171
current_version = get_current_version()
171172

172173
try:
@@ -189,7 +190,7 @@ def check_for_update():
189190
# Handle PYAPP separately
190191
if os.getenv('PYAPP'):
191192
if Confirm.ask("Would you like to update now?"):
192-
return self_update()
193+
return self_update(relaunch=relaunch)
193194
else:
194195
console.print("[yellow]Update skipped. You can manually update later.[/yellow]")
195196
return False
@@ -236,7 +237,7 @@ def pip_update_redfetch(update_command, latest_version):
236237
sys.exit(1)
237238

238239

239-
def self_update():
240+
def self_update(relaunch: bool = False):
240241
"""Update with PYAPP."""
241242
try:
242243
console.print("[bold]Performing self-update...[/bold]")
@@ -249,11 +250,33 @@ def self_update():
249250
executable_path = get_executable_path()
250251
update_command = [executable_path, 'self', 'update']
251252

252-
# Start the update process in a new console and exit the current one
253-
subprocess.Popen(
254-
update_command,
255-
creationflags=subprocess.CREATE_NEW_CONSOLE
256-
)
253+
if relaunch and sys.platform == "win32":
254+
update_cmdline = subprocess.list2cmdline(update_command)
255+
relaunch_cmdline = subprocess.list2cmdline([executable_path])
256+
batch_script = textwrap.dedent(f"""
257+
@echo off
258+
{update_cmdline}
259+
if %errorlevel% neq 0 (
260+
echo Update failed. Press any key to exit.
261+
pause > nul
262+
exit /b %errorlevel%
263+
)
264+
{relaunch_cmdline}
265+
(goto) 2>nul & del "%~f0"
266+
""").strip()
267+
with tempfile.NamedTemporaryFile(
268+
mode="w",
269+
delete=False,
270+
suffix=".bat",
271+
encoding="utf-8"
272+
) as batch_file:
273+
batch_file.write(batch_script)
274+
275+
subprocess.Popen(["cmd.exe", "/c", batch_file.name])
276+
sys.exit(0)
277+
278+
# Start the update process and exit the current one
279+
subprocess.Popen(update_command)
257280

258281
# Exit the current process to allow the update to proceed
259282
sys.exit(0)

0 commit comments

Comments
 (0)