fix(windows): der Deinstallierer liess 148 Dateien liegen und meldete Erfolg
Ampel / ampel (push) Successful in 54s
Ampel / ampel (push) Successful in 54s
Beim ersten echten Deinstallieren auf dem Rechner des Commanders gemessen:
Uninstall-Eintrag weg
Autostart weg
Verknuepfungen weg
Dateien 149 NOCH DA (davon 148 in fenster\EBWebView\)
Gemeldet wurde: "Rippy wurde entfernt."
Zwei Ursachen, beide behoben:
## 1. WebView2 ueberlebt Rippy
WebView2 startet eigene Prozesse (msedgewebview2.exe: Renderer, GPU, Netz,
Crashpad). Stirbt Rippy, laufen sie als Waisen weiter und halten den
Zwischenspeicher offen -- acht davon liefen noch, als ich nachsah. shutil.rmtree
scheiterte an jeder gesperrten Datei.
fenster.helfer_beenden() beendet sie jetzt VOR dem Loeschen. Gefiltert wird
ueber den --user-data-dir in der Befehlszeile: msedgewebview2.exe benutzen
auch andere Programme, und die alle zu beenden waere ein Uebergriff -- der
Nutzer verloere die Fenster fremder Anwendungen. Ein Test haelt fest, dass
erst gefiltert und dann beendet wird.
## 2. Der Fehler wurde verschluckt
`except OSError: pass` in der Loeschschleife. Ein "Rippy wurde entfernt" ueber
einem halb geleerten Ordner ist eine Falschaussage -- genau die Sorte stiller
Fehlschlag, vor der AGENTS.md warnt. Jetzt wird gesammelt, was nicht ging, und
mit dem Grund genannt.
Dazu im Aufraeum-Skript: `rmdir /s /q` statt `rmdir`. Ein blosses rmdir
scheitert an JEDER verbliebenen Datei und laesst den ganzen Ordner stehen --
selbst wenn spaeter nur noch eine Sperrdatei uebrig ist.
Ampel lokal: 612 gruen, ruff sauber.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ce4e7e6b8a
commit
a5e64f8e56
@@ -159,6 +159,68 @@ def speicherort() -> str:
|
||||
return ordner
|
||||
|
||||
|
||||
def helfer_skript(speicherort: str) -> str:
|
||||
"""Das PowerShell-Skript, das NUR unsere WebView2-Helfer beendet.
|
||||
|
||||
Reine Funktion, damit der Filter prüfbar ist, ohne etwas zu beenden.
|
||||
|
||||
## Warum das nötig ist (gemessen 28.08.2026)
|
||||
|
||||
Beim Deinstallieren blieben **148 Dateien** liegen, alle unter
|
||||
`fenster\\EBWebView\\`. Der Grund: WebView2 startet eigene Prozesse
|
||||
(`msedgewebview2.exe` — Renderer, GPU, Netz, Crashpad). Stirbt Rippy,
|
||||
laufen sie als Waisen weiter und halten den Zwischenspeicher offen.
|
||||
`shutil.rmtree` scheiterte, der Fehler wurde verschluckt, und der
|
||||
Deinstallierer meldete trotzdem „Rippy wurde entfernt."
|
||||
|
||||
## Warum über den Speicherort gefiltert wird
|
||||
|
||||
`msedgewebview2.exe` benutzen auch andere Programme. Sie alle zu beenden,
|
||||
wäre ein Übergriff — der Nutzer verlöre die Fenster fremder Anwendungen.
|
||||
Jeder Helfer trägt seinen `--user-data-dir` in der Befehlszeile; nur wer
|
||||
auf UNSEREN Ordner zeigt, gehört uns.
|
||||
"""
|
||||
ort = (speicherort or "").replace("'", "''")
|
||||
return (
|
||||
"Get-CimInstance Win32_Process -Filter \"Name='msedgewebview2.exe'\" "
|
||||
"| Where-Object { $_.CommandLine -like '*%s*' } "
|
||||
"| ForEach-Object { Stop-Process -Id $_.ProcessId -Force "
|
||||
"-ErrorAction SilentlyContinue }" % ort
|
||||
)
|
||||
|
||||
|
||||
def helfer_beenden(speicherort: str = None) -> bool:
|
||||
"""Beendet die WebView2-Helfer, die zu UNSEREM Speicherort gehören.
|
||||
|
||||
True, wenn der Versuch durchlief. Wirft nicht — ein Deinstallieren darf
|
||||
daran nicht scheitern.
|
||||
"""
|
||||
if os.name != "nt":
|
||||
return False
|
||||
import subprocess
|
||||
|
||||
ort = speicherort or speicherort_lesen()
|
||||
if not ort:
|
||||
return False
|
||||
from rippy.platform.winlauf import OHNE_FENSTER
|
||||
|
||||
try:
|
||||
ergebnis = subprocess.run(
|
||||
["powershell", "-NoProfile", "-NonInteractive", "-Command",
|
||||
helfer_skript(ort)],
|
||||
capture_output=True, text=True, timeout=60,
|
||||
creationflags=OHNE_FENSTER)
|
||||
except (OSError, subprocess.SubprocessError):
|
||||
return False
|
||||
return ergebnis.returncode == 0
|
||||
|
||||
|
||||
def speicherort_lesen() -> str:
|
||||
"""Der Speicherort OHNE ihn anzulegen — fürs Aufräumen."""
|
||||
basis = os.environ.get("LOCALAPPDATA") or os.path.expanduser("~")
|
||||
return os.path.join(basis, "Rippy", "fenster")
|
||||
|
||||
|
||||
def oeffnen(adresse: str, titel: str = TITEL, breite: int = BREITE,
|
||||
hoehe: int = HOEHE) -> None:
|
||||
"""Öffnet das Fenster und kehrt erst zurück, wenn es geschlossen wird.
|
||||
|
||||
@@ -125,6 +125,48 @@ def test_erfolgreiches_fenster_oeffnet_keinen_browser(monkeypatch):
|
||||
assert gerufen == []
|
||||
|
||||
|
||||
# ── Die WebView2-Helfer ─────────────────────────────────────────────────
|
||||
def test_helfer_werden_ueber_den_speicherort_gefiltert():
|
||||
"""DER Befund vom 28.08.2026: Nach dem Deinstallieren blieben 148 Dateien
|
||||
liegen, alle unter `fenster\\EBWebView\\`. WebView2 startet eigene
|
||||
Prozesse (Renderer, GPU, Netz, Crashpad); stirbt Rippy, laufen sie als
|
||||
Waisen weiter und halten den Zwischenspeicher offen."""
|
||||
s = fenster.helfer_skript(r"C:\Users\X\AppData\Local\Rippy\fenster")
|
||||
assert "msedgewebview2.exe" in s
|
||||
assert r"C:\Users\X\AppData\Local\Rippy\fenster" in s
|
||||
assert "Stop-Process" in s
|
||||
|
||||
|
||||
def test_der_filter_trifft_NUR_unsere_helfer():
|
||||
"""`msedgewebview2.exe` benutzen auch andere Programme. Sie alle zu
|
||||
beenden waere ein Uebergriff — der Nutzer verloere die Fenster fremder
|
||||
Anwendungen. Ohne `Where-Object` auf den Speicherort passiert genau das."""
|
||||
s = fenster.helfer_skript(r"C:\Rippy\fenster")
|
||||
assert "Where-Object" in s, "ohne Filter wuerden FREMDE Fenster sterben"
|
||||
assert s.index("Where-Object") < s.index("Stop-Process"), \
|
||||
"erst filtern, dann beenden"
|
||||
|
||||
|
||||
def test_apostroph_im_pfad_bricht_das_skript_nicht():
|
||||
"""In PowerShell wird ein Apostroph durch VERDOPPELN maskiert. Ohne das
|
||||
bricht ein Pfad wie C:\\Users\\O'Brien\\… das Skript mitten entzwei."""
|
||||
s = fenster.helfer_skript(r"C:\Users\O'Brien\Rippy\fenster")
|
||||
assert "O''Brien" in s
|
||||
assert s.count("'") % 2 == 0
|
||||
|
||||
|
||||
def test_ohne_windows_werden_keine_helfer_beendet():
|
||||
if os.name == "nt":
|
||||
pytest.skip("prueft das Verhalten auf Nicht-Windows")
|
||||
assert fenster.helfer_beenden("/tmp/x") is False
|
||||
|
||||
|
||||
def test_leerer_speicherort_beendet_nichts(monkeypatch):
|
||||
"""Ein leerer Filter wuerde auf ALLE msedgewebview2-Prozesse passen."""
|
||||
monkeypatch.setattr(fenster, "speicherort_lesen", lambda: "")
|
||||
assert fenster.helfer_beenden("") is False
|
||||
|
||||
|
||||
# ── Der Speicherort ─────────────────────────────────────────────────────
|
||||
def test_speicherort_liegt_bei_rippy(monkeypatch, tmp_path):
|
||||
"""Im TEMP waere er bei jedem Aufraeumen weg — und beim Deinstallieren
|
||||
|
||||
@@ -55,7 +55,16 @@ def test_skript_loescht_sich_selbst():
|
||||
def test_ordner_ohne_abschliessenden_trenner():
|
||||
"""rmdir will den Ordner OHNE Schluss-Backslash — mit scheitert es."""
|
||||
s = windows_app.aufraeum_skript(r"C:\R\Rippy.exe", "C:" + BACKSLASH + "R" + BACKSLASH)
|
||||
assert 'rmdir "' + r"C:\R" + '"' in s
|
||||
assert 'rmdir /s /q "' + r"C:\R" + '"' in s
|
||||
|
||||
|
||||
def test_skript_raeumt_den_ordner_MIT_inhalt():
|
||||
"""DER Befund vom 28.08.2026: Nach dem Deinstallieren blieben 148 Dateien
|
||||
liegen (WebView2-Zwischenspeicher, dessen Prozesse Rippy ueberlebt
|
||||
hatten). Ein blosses `rmdir` scheitert an JEDER verbliebenen Datei und
|
||||
laesst den ganzen Ordner stehen."""
|
||||
s = windows_app.aufraeum_skript(r"C:\R\Rippy.exe", r"C:\R")
|
||||
assert "rmdir /s /q" in s, "ohne /s /q bleibt jeder nicht leere Ordner stehen"
|
||||
|
||||
|
||||
# ── Installation (echt, in einem Testordner) ────────────────────────────
|
||||
|
||||
@@ -269,25 +269,47 @@ def deinstallieren(still: bool = False) -> None:
|
||||
|
||||
reg.autostart_entfernen()
|
||||
reg.austragen()
|
||||
|
||||
# ⚠️ ZUERST die WebView2-Helfer beenden (Befund 28.08.2026).
|
||||
#
|
||||
# Beim ersten echten Deinstallieren blieben 148 Dateien liegen, alle
|
||||
# unter `fenster\EBWebView\`. WebView2 startet eigene Prozesse
|
||||
# (msedgewebview2.exe: Renderer, GPU, Netz, Crashpad); stirbt Rippy,
|
||||
# laufen sie als Waisen weiter und halten den Zwischenspeicher offen.
|
||||
# Danach ging `shutil.rmtree` nicht mehr — und der Fehler wurde
|
||||
# verschluckt, waehrend „Rippy wurde entfernt" gemeldet wurde.
|
||||
from rippy import fenster as fenster_modul
|
||||
|
||||
fenster_modul.helfer_beenden(os.path.join(ordner, "fenster"))
|
||||
|
||||
laeuft_von_hier = os.path.abspath(_eigene_datei()).lower().startswith(
|
||||
os.path.abspath(ordner).lower())
|
||||
|
||||
# Die eigene Datei kann sich nicht selbst loeschen, solange sie laeuft.
|
||||
# Also: alles andere jetzt, die EXE per Aufraeum-Befehl danach.
|
||||
geblieben = []
|
||||
for name in os.listdir(ordner) if os.path.isdir(ordner) else []:
|
||||
pfad = os.path.join(ordner, name)
|
||||
if laeuft_von_hier and os.path.abspath(pfad).lower() == os.path.abspath(_eigene_datei()).lower():
|
||||
continue
|
||||
try:
|
||||
shutil.rmtree(pfad) if os.path.isdir(pfad) else os.remove(pfad)
|
||||
except OSError:
|
||||
pass
|
||||
except OSError as e:
|
||||
# NICHT verschlucken. Ein „Rippy wurde entfernt" ueber einem
|
||||
# halb geleerten Ordner ist eine Falschaussage.
|
||||
geblieben.append("%s (%s)" % (name, e.strerror or e))
|
||||
|
||||
if laeuft_von_hier:
|
||||
selbst_loeschen(_eigene_datei(), ordner)
|
||||
|
||||
if not still:
|
||||
melden("Rippy wurde entfernt.")
|
||||
if geblieben:
|
||||
melden("Rippy wurde entfernt — diese Reste waren gesperrt und "
|
||||
"werden gleich nachgeholt:")
|
||||
for eintrag in geblieben:
|
||||
melden(" " + eintrag)
|
||||
else:
|
||||
melden("Rippy wurde entfernt.")
|
||||
|
||||
|
||||
AUFRAEUM_SKRIPT = """@echo off
|
||||
@@ -299,7 +321,11 @@ for /l %%n in (1,1,15) do (
|
||||
)
|
||||
goto ende
|
||||
:weg
|
||||
rmdir "{ordner}" >nul 2>&1
|
||||
rem /s /q, nicht nur rmdir: Ein blosses rmdir scheitert an JEDER
|
||||
rem verbliebenen Datei. Am 28.08.2026 blieben 148 Dateien im
|
||||
rem WebView2-Zwischenspeicher liegen, weil deren Prozesse Rippy ueberlebt
|
||||
rem hatten -- der Ordner blieb dann samt Inhalt stehen.
|
||||
rmdir /s /q "{ordner}" >nul 2>&1
|
||||
:ende
|
||||
del /q "%~f0" >nul 2>&1
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user