Skip to content

Commit 21c32c2

Browse files
Lukas Geigerclaude
andcommitted
fix: contextmenu command broken when installed from PyInstaller exe
When `clf context --install` was run from the built exe, _command() produced: `"CloudLockFixer.exe" "clf_launcher.pyw" gui-add ...` The .pyw file does not exist in the build dir, and argparse received it as sys.argv[1] (invalid subcommand) → silent crash, no dialog ever opened. Fix: detect sys.frozen and call the exe directly without a script path. Adds test_contextmenu.py covering both frozen and source code cases. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent ba57404 commit 21c32c2

2 files changed

Lines changed: 50 additions & 0 deletions

File tree

src/cloudlockfixer/contextmenu.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919

2020

2121
def _command(op: str) -> str:
22+
# PyInstaller-Exe: sys.frozen ist True, clf_launcher.pyw existiert nicht im Build-Dir.
23+
# Exe direkt aufrufen — sie versteht gui-add als subcommand.
24+
if getattr(sys, "frozen", False):
25+
return f'"{sys.executable}" gui-add --op {op} --src "%1"'
2226
return f'"{pythonw()}" "{launcher()}" gui-add --op {op} --src "%1"'
2327

2428

tests/test_contextmenu.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
"""Tests fuer contextmenu._command() — insbesondere PyInstaller-frozen-Erkennung."""
2+
import sys
3+
import types
4+
import unittest.mock as mock
5+
6+
import pytest
7+
8+
9+
def _get_command(op: str, frozen: bool, exe: str = r"C:\App\clf.exe"):
10+
"""Importiert contextmenu mit simuliertem sys.frozen und sys.executable."""
11+
# Modul neu laden damit Patches wirken
12+
import importlib
13+
with mock.patch.object(sys, "frozen", frozen, create=True), \
14+
mock.patch.object(sys, "executable", exe):
15+
import cloudlockfixer.contextmenu as cm
16+
importlib.reload(cm)
17+
return cm._command(op)
18+
19+
20+
def test_command_frozen_omits_script_path():
21+
"""PyInstaller-Exe: kein pyw-Pfad, direkte Exe + subcommand."""
22+
exe = r"C:\App\CloudLockFixer.exe"
23+
cmd = _get_command("rename", frozen=True, exe=exe)
24+
assert exe in cmd
25+
assert ".pyw" not in cmd
26+
assert "gui-add" in cmd
27+
assert "--op rename" in cmd
28+
assert "--src" in cmd
29+
30+
31+
def test_command_not_frozen_includes_launcher():
32+
"""Quell-Installation: pythonw + clf_launcher.pyw als Argumente."""
33+
cmd = _get_command("move", frozen=False)
34+
assert ".pyw" in cmd or "launcher" in cmd.lower() or "clf_launcher" in cmd
35+
assert "gui-add" in cmd
36+
assert "--op move" in cmd
37+
38+
39+
def test_command_frozen_format(tmp_path):
40+
"""Befehl ist korrekt quotiert und enthält %1 als src-Platzhalter."""
41+
exe = str(tmp_path / "CloudLockFixer.exe")
42+
cmd = _get_command("delete", frozen=True, exe=exe)
43+
assert '"%1"' in cmd
44+
assert "--op delete" in cmd
45+
# Exe-Pfad muss gequotet sein (wegen möglicher Leerzeichen)
46+
assert f'"{exe}"' in cmd

0 commit comments

Comments
 (0)