Windows-Shell-Integration heute ── Kontextmenüs, Dateizuordnungen und was sich unter Windows 11 geändert hat

· · Windows, Shell-Erweiterungen, Kontextmenü, Dateizuordnung, COM, Windows 11, Datei-Explorer, MSIX, Windows-Entwicklung

Ich wurde mit „wir haben die PCs durch Windows 11 ersetzt, und das Kontextmenü der App, die Sie uns vor Jahren gebaut haben, ist verschwunden“ konsultiert. Beim genaueren Zuhören war es nicht verschwunden. Rechtsklick auf eine Datei, „Weitere Optionen anzeigen“ am unteren Ende des Menüs wählen, und das vertraute Menü erscheint genau wie immer. Mit anderen Worten: Die Menüeinträge der internen App waren einen Klick weiter nach innen versteckt worden. Vom Feld hören wir „es ist ein Extra-Klick“ und „Anfragen, dass sie den Eintrag nicht finden, haben zugenommen“.

Das ist weder ein Ausfall noch eine Fehlkonfiguration; es ist eine Windows-11-Entwurfsänderung. Das Kontextmenü des Datei-Explorers wurde zu einer Zweischichtstruktur, alt und neu, und die Bedingungen, einen Eintrag ins neue Menü zu setzen, wurden etwas völlig anderes als zuvor.

Zugleich ist die Dateizuordnungs- und Shell-Erweiterungsmaschinerie darunter noch die alte Welt von COM und der Registrierung. Ein Erweiterungsschlüssel zeigt auf eine ProgID, das Verb der ProgID hält eine Befehlszeile, und eine aufwendigere Erweiterung läuft als In-Process-COM-Server (DLL), der in den Explorer geladen wird — diese Struktur hat sich in mehr als zwanzig Jahren nicht geändert. Wenn Sie nicht sowohl das unveränderte Fundament als auch das Menü kennen, das Windows 11 in zwei Teile gespalten hat, können Sie „das Menü erscheint nicht“, „es ist versteckt“ oder „es erscheint doppelt“ nicht isolieren.

Dieser Artikel richtet sich an IT-Personal in kleinen und mittleren Unternehmen und an Windows-Entwickler, die Geschäftsanwendungen betreuen. Er knüpft in einem Bild die Dreischichtstruktur der Dateizuordnung, die Fallstricke klassischer Shell-Erweiterungen, wie man das neue Windows-11-Kontextmenü ansteuert, sowie Installationsprogramm-Registrierung, Aufräumen und Fehlerbehebung zusammen.

1. Zuerst das Fazit

  • Das Fundament von Kontextmenü und Dateizuordnung ist die dreischichtige Registrierungsstruktur „Erweiterungsschlüssel → ProgID → Verb“. Der Erweiterungsschlüssel ist ein Zeiger auf eine ProgID, die ProgID ist die Substanz, und shell\<verb>\command darunter hält die Befehlszeile.1
  • HKEY_CLASSES_ROOT (HKCR) ist kein unabhängiger Hive; es ist eine zusammengeführte Ansicht von HKLM\Software\Classes und HKCU\Software\Classes. Schreiben Sie die Alle-Benutzer-Registrierung nach HKLM und die Pro-Benutzer-Registrierung nach HKCU, und behandeln Sie HKCR als schreibgeschützt.2
  • Die Standard-App (die App, die beim Doppelklick öffnet) ist so entworfen, dass sie der Benutzer wählt, und ein Programm kann sie nicht stehlen. Das Betriebssystem schützt die Wahl des Benutzers; was ein Installationsprogramm tun kann, ist, sich als Kandidat zu registrieren.3
  • Eine klassische Shell-Erweiterung ist eine In-Process-COM-DLL, die in den Explorer geladen wird. Ein Absturz oder eine Verzögerung in der Erweiterung greift auf den Explorer als Ganzes über (und auf andere Apps, die die Shell nutzen); eine 64-Bit-Umgebung braucht eine 64-Bit-DLL; und eine Implementierung in verwaltetem Code ist nicht unterstützt.45
  • Unter Windows 11 ist das Kontextmenü in zwei Teile zerfallen. Die einzigen Befehle, die im neuen Menü erscheinen, sind solche, die mit IExplorerCommand plus Paketidentität registriert sind; klassische IContextMenu-Erweiterungen werden ins alte Menü unter „Weitere Optionen anzeigen“ (Umschalt+F10) verschoben.67
  • Der offizielle Weg, einen eigenen Befehl ins neue Menü zu setzen, ist, eine native DLL, die IExplorerCommand implementiert, in einem MSIX-Manifest zu registrieren (desktop4:FileExplorerContextMenus). Eine App, die nicht MSIX werden kann, kann die Identität allein mit einem Sparse-Paket (MSIX mit externem Speicherort) erhalten.78
  • Wenn Sie nur „mit dieser App öffnen“ wollen, reichen eine Zuordnung und ein statisches Verb immer noch. Sie brauchen keine Shell-Erweiterungs-DLL, und Microsoft selbst sagt klar „wählen Sie die einfachste Methode, die die Anforderungen erfüllt (ein statisches Verb)“.9
  • Nach Registrierung oder Änderung benachrichtigen Sie mit SHChangeNotify(SHCNE_ASSOCCHANGED); bei der Deinstallation löschen Sie die ProgID, löschen aber nicht den Standardwert des Erweiterungsschlüssels — das ist die offizielle Anleitung. Shell-Integration schließt den Entwurf des Aufräumens ein.110

In einem Satz: die Welt der Zuordnungen und Verben ist unverändert; nur wie das Menü gezeigt wird, ist unter Windows 11 in zwei Teile zerfallen. Unten gehen wir das vom Fundament her durch.

2. Wie Dateizuordnung funktioniert — die Dreischichtstruktur Erweiterungsschlüssel → ProgID → Verb

2.1. Die Dreischichtstruktur an einem Beispiel lesen

Was passiert, wenn Sie eine Datei einer gegebenen Erweiterung doppelklicken, entscheiden drei Schichten von Registrierungsschlüsseln.1

HKEY_CLASSES_ROOT
   .kmrpt                                  ← (1) Erweiterungsschlüssel
      (Default) = KomuraSoft.Report.1      ←     Ein Zeiger, der nur die ProgID nennt
      OpenWithProgids
         KomuraSoft.Report.1               ←     Ein Kandidat unter „Öffnen mit“
   KomuraSoft.Report.1                     ← (2) ProgID (die Substanz der Zuordnung)
      (Default) = Komura Report document
      DefaultIcon
         (Default) = "C:\Program Files\KomuraSoft\Report.exe",0
      shell                                ← (3) Liste der Verben
         open
            command
               (Default) = "C:\Program Files\KomuraSoft\Report.exe" "%1"
  • (1) Der Erweiterungsschlüssel (.kmrpt) zeigt nur als Standardwert auf einen ProgID-Namen. Hier direkt einen Befehl zu schreiben ist ein Fehler.
  • (2) Die ProgID (KomuraSoft.Report.1) ist die Substanz der Zuordnung; sie hält den Anzeigenamen, das Symbol und die Verbliste.
  • (3) Ein Verb ist eine Aktion wie „öffnen“ oder „drucken“, und der Standardwert von shell\open\command ist die Befehlszeile, die tatsächlich gestartet wird.

Diese Trennung ist der Grund, warum Sie mehrere Erweiterungen (.kmrpt und .kmrpt-file zum Beispiel) auf dieselbe ProgID zeigen lassen oder die ProgID beim Upgrade der App tauschen können.

Die Dreischichtstruktur der DateizuordnungDer Erweiterungsschlüssel ist ein Zeiger, dessen Standardwert eine ProgID nennt; die ProgID ist die Substanz, die Anzeigename, Symbol und Verbliste hält; und der Standardwert von command unter dem Verb ist die Befehlszeile, die tatsächlich gestartet wirdnennt die ProgID als StandardErweiterungsschlüssel .kmrptProgID KomuraSoft.Report.1Verb(open und andere unter shell)command-StandardwertReport.exe wird gestartetHält auch den Anzeigenamen und DefaultIcon

Abbildung 1: Der Erweiterungsschlüssel ist ein Zeiger, die ProgID ist die Substanz, und das command des Verbs ist die Befehlszeile, die tatsächlich gestartet wird.

2.2. HKCR ist eine „zusammengeführte Ansicht“ — wohin Sie schreiben, ändert die Bedeutung

Das Beispiel oben steht unter HKEY_CLASSES_ROOT (HKCR), aber HKCR ist kein physischer Speicherort; es ist eine zusammengeführte Ansicht von HKLM\Software\Classes und HKCU\Software\Classes. Existiert derselbe Schlüssel auf beiden Seiten, gewinnt die HKCU-Seite.2

HKCR ist eine zusammengeführte AnsichtHKCR ist HKLM- und HKCU-Classes übereinandergelegt; existiert derselbe Schlüssel auf beiden Seiten, gewinnt HKCU; schreiben Sie die Registrierung ausdrücklich nach HKLM oder HKCU und behandeln Sie HKCR als schreibgeschütztHKLM\\Software\\Classes(alle Benutzer)HKCR(zusammengeführte Ansicht)HKCU\\Software\\Classes(pro Benutzer)Existiert derselbe Schlüssel, gewinnt HKCUAls schreibgeschützt behandeln(zur Bestätigung)

Abbildung 2: HKCR ist, wie HKLM- und HKCU-Classes aussehen, wenn sie zusammengelegt sind; nennen Sie immer die eine oder die andere als Schreibziel.

Schreibziel Bedeutung Erforderliche Rechte
HKLM\Software\Classes Registrierung gemeinsam für alle Benutzer Administrator
HKCU\Software\Classes Registrierung nur für diesen Benutzer Keine
Direkt nach HKCR schreiben Je nachdem, wo der vorhandene Schlüssel schon lebt, verteilt Abhängig

In der Praxis ist die sichere Teilung, die Registrierung immer ausdrücklich nach HKLM oder HKCU zu schreiben und HKCR als schreibgeschützt (zur Bestätigung) zu behandeln. Das Verhältnis zur WOW64-Registrierungsumleitung lohnt sich ebenfalls zu sortieren. Zuordnungsdaten direkt unter HKLM\Software\Classes wie Erweiterungsschlüssel und ProgIDs sind seit Windows 7 zwischen der 32-Bit- und der 64-Bit-Registrierungsansicht geteilt, sodass ein 32-Bit-Installationsprogramm, das sie schreibt, nicht auf die Wow6432Node-Seite entkommt. Einige COM-Registrierungsunterschlüssel wie Classes\CLSID dagegen werden umgeleitet, und wenn Sie eine Shell-Erweiterung (In-Process-COM) registrieren, zählt die 32-Bit-/64-Bit-Schreibteilung. Einzelheiten stehen in „Registry-32-Bit/64-Bit-Umleitung und Virtualisierungsfallen — Wow6432Node und das Problem „Der Wert, den ich geschrieben habe, ist nicht da““.

2.3. Registrierung auf der App-Seite — App Paths, Applications, RegisteredApplications

Es gibt auch drei Arten von Registrierung auf der App-Seite, gepaart mit der Dateiseite (Erweiterung und ProgID).11

  • App Paths (HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths): Registrierung, die ShellExecuteEx erlaubt, allein über den Namen der ausführbaren Datei zu starten. Microsoft empfiehlt das, weil Sie die PATH-Umgebungsvariable nicht verschmutzen müssen.
  • Applications (HKCR\Applications\<app.exe>): Definiert die Standardweise zu öffnen, wenn eine beliebige Datei unter „Öffnen mit“ übergeben wird, und den Anzeigenamen der App (FriendlyAppName).
  • RegisteredApplications + Capabilities: Deklariert die Erweiterungen und MIME-Typen, die die App behandeln kann, und ist die Registrierung, die sie als Kandidat auf der Windows-Seite Standard-Apps erscheinen lässt.

Die meisten Beratungen „unsere App erscheint nicht in der Liste der Standard-Apps“ sind Fälle, in denen die ProgID registriert und diese Capabilities-Registrierung weggelassen wurde.

Die drei Arten der Registrierung auf der App-SeiteDie App-seitige Registrierung hat drei Arten — App Paths, Applications und RegisteredApplications — zuständig jeweils für den Start allein über den Dateinamen, die Standardweise zu öffnen unter Öffnen mit, und das Erscheinen auf der Seite Standard-AppsApp-seitige RegistrierungApp PathsApplicationsRegisteredApplicationsStart allein über den DateinamenStandard unter Öffnen mitErscheint auf der Seite Standard-AppsEine Capabilities-Deklaration ist nötig

Abbildung 3: Es gibt drei Arten der App-seitigen Registrierung, und als Standard-Apps-Kandidat zu erscheinen erfordert eine Capabilities-Registrierung.

2.4. Die Standard-App gehört dem Benutzer — UserChoice-Schutz

Eine ProgID als Standardwert des Erweiterungsschlüssels zu schreiben macht sie nicht von selbst zur Standard-App. Das Ergebnis der ausdrücklichen Benutzerwahl unter „Öffnen mit“ und Ähnlichem wird in HKCU\...\Explorer\FileExts\<extension>\UserChoice gehalten, und die Zuordnungsauflösung bevorzugt diese Seite.

Und der wichtige Punkt ist, dass Windows die programmatische Änderung der Standard-App nicht unterstützt. Standard-App-Einstellungen sind so entworfen, dass sie der Benutzer über die Systemeinstellungen-UI vornimmt; UserChoice-Daten sind verschleiert, und ein Filtertreiber (UCPD.sys) blockiert Schreibvorgänge von Apps. In einer verwalteten Umgebung ist Gruppenrichtlinie / MDM-Richtlinie das offizielle Mittel.3

Dass Werkzeuge wie SetUserFTA, die „den Hash nachahmen und ihn umschreiben“, benutzt wurden, ist die andere Seite dieses Schutzes. Was Sie ins Installationsprogramm einer internen App legen sollten, ist nicht das Stehlen der Vorgabe, sondern die drei (a) korrekte Registrierung der ProgID und der Verben, (b) sich zu OpenWithProgIds hinzufügen, und (c) bei Bedarf zur Einstellungsseite lenken.

Standard-App-Auflösung und UserChoice-SchutzDas Ergebnis einer ausdrücklichen Benutzerwahl wird in UserChoice gehalten und in der Zuordnungsauflösung bevorzugt; UCPD.sys blockiert Umschreibungen von Apps, also kann ein Installationsprogramm sich als Kandidat registrieren und zur Einstellungsseite lenkenbevorzugtUCPD.sys blockiert esUserChoice(die Wahl des Benutzers)ZuordnungsauflösungStandardwert des ErweiterungsschlüsselsUmschreiben von einer AppDie Aufgabe des InstallationsprogrammsProgID und Verben registrierenZu OpenWithProgIds hinzufügenZur Einstellungsseite lenken

Abbildung 4: Die Zuordnungsauflösung bevorzugt die Wahl des Benutzers (UserChoice), und das Betriebssystem schützt sie vor Umschreibungen durch Apps.

3. Verben außer „Öffnen“ — print, edit, runas, eigene Verben

Ein Verb ist nicht nur open. Standardverben, deren Bedeutung das Betriebssystem kennt, umfassen edit, print, play und preview sowie open, und ein Standardverb erhält automatisch einen Anzeigenamen, der der Betriebssystemsprache folgt. Das Standardverb beim Doppelklick wird in der Reihenfolge entschieden: Standardwert des shell-Schlüssels → erstes Verb in der Registrierung → openopenwith.12

Reihenfolge, in der das Standardverb entschieden wirdDas Standardverb beim Doppelklick ist das erste, das in der Reihenfolge Standardwert des shell-Schlüssels, erstes Verb in der Registrierung, open, openwith gefunden wirdfalls keinerfalls keinesfalls keinesStandardwert des shell-SchlüsselsErstes Verb in der Registrierungopenopenwith

Abbildung 5: Das Standardverb beim Doppelklick ist das erste, das in dieser Reihenfolge gefunden wird.

Wenn Sie eine eigene Aktion hinzufügen wollen, registrieren Sie ein eigenes Verb.

KomuraSoft.Report.1
   shell
      open
         command
            (Default) = "C:\Program Files\KomuraSoft\Report.exe" "%1"
      print
         command
            (Default) = "C:\Program Files\KomuraSoft\Report.exe" /print "%1"
      verify                          ← eigenes Verb
         (Default) = Verify report (&V)   ← Menüanzeigename
         command
            (Default) = "C:\Program Files\KomuraSoft\Report.exe" /verify "%1"

Drei kleine Tatsachen, die zu kennen hilft.

  • Registrieren Sie ein Verb namens runas, und Sie definieren einen Erhöhungstart, der „Als Administrator ausführen“ entspricht, und er wird auch verwendet, wenn eine API der ShellExecute-Familie runas angibt.
  • Legen Sie einen leeren Wert namens Extended auf den Verbschlüssel, und es wird ein erweitertes Verb, das nur bei Umschalt+Rechtsklick gezeigt wird. Praktisch, um eine gefährliche, selten genutzte Operation zu verstecken.12
  • Einige Zuordnungen älterer Apps haben noch eine Konfiguration, die ein Dokument mit DDE (der Schlüssel ddeexec) in einen bestehenden Prozess schickt, aber ein Verb über DDE zu starten ist bereits ein Deprecated-Erbe. Es gibt keinen Grund, es neu zu schreiben.12

Ein weiterer Unfall, der oft passiert, ist das Anführungszeichen in der Befehlszeile. Kann ein Element der Befehlszeichenfolge ein Leerzeichen enthalten, müssen Sie es in Anführungszeichen setzen. Das gilt natürlich für einen EXE-Pfad wie C:\Program Files\..., und %1 (der Pfad der ausgewählten Datei) sollte immer als "%1" geschrieben werden. Sie können nicht garantieren, dass ein Benutzerdateipfad kein Leerzeichen enthält. Ein unquoted My Program.exe wird als „starte My mit dem Argument Program.exe“ interpretiert.13

Der Anführungszeichen-Unfall in der BefehlszeileEin unquoted Befehl wird am Leerzeichen gespalten und als Start von My mit dem Argument Program.exe fehlinterpretiert, also sollten ein EXE-Pfad, der ein Leerzeichen enthalten kann, und %1, das den ausgewählten Dateipfad darstellt, immer in Anführungszeichen gesetzt werdenam Leerzeichen gespaltenUnquoted BefehlAls Start einer anderen EXE fehlinterpretiertQuoted BefehlStartet wie beabsichtigtSetzen Sie den EXE-Pfad in AnführungszeichenSetzen Sie auch %1 immer in Anführungszeichen

Abbildung 6: Ein unquoted Befehl wird am Leerzeichen falsch gespalten, also setzen Sie EXE-Pfad und %1 immer in Anführungszeichen.

Der bisherige Nur-Registrierungs-Mechanismus (ein statisches Verb) lässt sich ohne eine einzige DLL realisieren und riskiert nicht, den Explorer instabil zu machen. Microsoft selbst sagt wiederholt „bevor Sie eine Shell-Erweiterung schreiben, prüfen Sie, ob das einfachste statische Verb, das die Anforderungen erfüllt, reicht“.9

4. Klassische Shell-Erweiterungen — eine DLL, die im Explorer läuft

4.1. Arten von Shell-Erweiterungen

Anforderungen, die ein statisches Verb nicht erfüllt — „das Menü dynamisch je nach Auswahl ändern“, „das Symbol oder das Eigenschaftenblatt ersetzen“ — nutzen einen Shell-Erweiterungshandler. Repräsentative Arten sind die folgenden.4

Handler Hauptschnittstelle Was er tun kann
Kontextmenühandler IContextMenu + IShellExtInit Menüeinträge dynamisch hinzufügen und steuern
Symbolhandler / Symbolüberlagerung IExtractIcon / IShellIconOverlayIdentifier Symbol pro Datei und Überlagerung
Eigenschaftenblatthandler IShellPropSheetExt Eine Registerkarte zum Eigenschaftenblatt hinzufügen
Miniatur / Infotip IThumbnailProvider / IQueryInfo Miniaturansicht und Hover-Beschreibung
Drag-and-Drop- / Copy-Hook-Handler IDropTarget / ICopyHook Beim Ablegen oder bei Kopieren/Verschieben eingreifen

Diese sind alle als COM-Klassen implementiert und in der Registrierung per CLSID registriert. Die Idee von COM selbst steht in „Was sind COM / ActiveX / OCX? – Unterschiede und Zusammenhänge im Überblick“.

4.2. Was es bedeutet, ein In-Process-COM-Server zu sein

Das Wesen einer klassischen Shell-Erweiterung ist, dass sie ein In-Process-COM-Server (DLL) ist, der in den Explorer (oder in jede App, die einen gemeinsamen Dateidialog geöffnet hat) geladen wird. Jede Vorsichtsmaßnahme folgt daraus.4

  • Stürzt die Erweiterung ab, nimmt sie den Explorer mit. Hängt sie, friert ein Rechtsklick mehrere Sekunden ein. Der Schaden beschränkt sich auch nicht auf den Explorer; er erreicht jede App, die einen Dateiöffnen-Dialog angezeigt hat.
  • Der Menüaufbau geschieht auf dem UI-Thread, also dürfen Sie zur Anzeigezeit keine langsame Arbeit wie Netzwerkzugriff oder Datei-E/A tun.
  • Registrieren Sie das Threading-Modell in der Regel als Apartment.
Kollateralschadenstruktur einer In-Process-ErweiterungEine Shell-Erweiterungs-DLL wird nicht nur in den Explorer, sondern auch in den Prozess jeder App geladen, die einen Dateidialog geöffnet hat, sodass ein Absturz oder Hänger in der Erweiterung auf den ganzen Hostprozess übergreiftin-process geladenin-process geladenShell-Erweiterungs-DLLExplorerJede App, die einen Dialog öffnetEin Absturz oder Hänger greift überZur Anzeigezeit keine langsame Arbeit

Abbildung 7: Die Erweiterungs-DLL läuft im Hostprozess, sodass ein Absturz oder Hänger auf den Host als Ganzes übergreift.

Untersuchen Sie eine Beratung wie „der Explorer friert ein, wenn ich einen bestimmten Ordner öffne“ oder „ein Rechtsklick dauert fünf Sekunden“, und es ist nicht selten, dass die Ursache eine Drittanbieter-Shell-Erweiterung statt der internen App ist. Isolationsmethoden stehen in Kapitel 8.

4.3. Bittigkeit angleichen — eine 64-Bit-Umgebung braucht eine 64-Bit-DLL

Eine In-Process-DLL muss zur Bittigkeit des Prozesses passen, der sie lädt. Der Explorer unter 64-Bit-Windows ist ein 64-Bit-Prozess, also wird eine nur als 32-Bit gebaute Shell-Erweiterungs-DLL nie geladen und erscheint überhaupt nicht im Menü. Es gibt auch keinen Fehler, daher ist das eine Standardursache von „ich habe sie registriert, aber sie erscheint nicht“. Eine 32-Bit-App-Hauptkomponente mit einer 64-Bit-Shell-Erweiterungs-DLL zu kombinieren ist eine legitime Konfiguration, aber Sie müssen die Tatsache im Blick behalten, dass die COM-Registrierung nach Bittigkeit teilt (Wow6432Node). Der Start vom command eines Verbs ist eine eigene-Prozess-EXE, also unterliegt er dieser Einschränkung nicht (sie als 32-Bit-EXE zu lassen ist in Ordnung).

Bittigkeit einer Shell-Erweiterungs-DLL angleichenDie einzige Shell-Erweiterungs-DLL, die ein 64-Bit-Explorer laden kann, ist eine 64-Bit-DLL; eine nur-32-Bit-DLL erscheint nie im Menü und erzeugt keinen Fehler; eine vom Verb-Command gestartete EXE ist ein eigener Prozess und unterliegt der Einschränkung nichtkann ladenkann nicht ladeneigener Prozess64-Bit-Explorer64-Bit-Shell-Erweiterungs-DLLNur-32-Bit-DLLErscheint nicht im Menü, ohne FehlerVom Verb gestartete EXEAls 32-Bit in Ordnung

Abbildung 8: Die einzige in den 64-Bit-Explorer geladene DLL ist eine 64-Bit-DLL; eine vom Verb gestartete EXE unterliegt dieser Einschränkung nicht.

4.4. Warum Sie sie nicht in verwaltetem Code schreiben dürfen

Ich bekomme oft die Frage „kann ich eine Shell-Erweiterung in C# schreiben“, aber Microsoft hat klar gesagt, dass das Schreiben einer In-Process-Shell-Erweiterung in verwaltetem Code (.NET) nicht empfohlen und außerhalb des Supports ist.5

Der Grund ist die Natur der Erweiterung, die in einen beliebigen Prozess geladen wird. CLR-Versionskollisionen (besonders unter .NET Framework 4), das Problem, dass die CLR während des Wartens auf eine Sperre in die Nachrichtenschleife wiedereintritt, und nicht deterministische Objektlebensdauer durch Garbage Collection, die mit dem Referenzzählvertrag von COM kollidiert, sind strukturelle Gründe, warum die Host-App instabil wird. Einige Punkte wurden auf .NET Framework 4 und später und auf modernem .NET gemildert, aber die offizielle Position hat sich nicht geändert.

Die praktische Richtlinie ist einfach. Schreiben Sie eine In-Process-Erweiterung in nativem C++. Wenn Sie verwalteten Code nutzen wollen, machen Sie daraus eine normale EXE, die vom command eines Verbs gestartet wird, oder eine Out-of-Process-Erweiterung, die in einem eigenen Prozess läuft (ein Vorschauhandler und Ähnliches).5

Beurteilen, ob verwalteter Code erlaubt istEine In-Process-Erweiterung, die im Explorer läuft, wird in der Regel in nativem C++ geschrieben; wenn Sie verwalteten Code wollen, machen Sie daraus eine normale vom Verb-Command gestartete EXE oder eine Out-of-Process-Erweiterung, die in einem eigenen Prozess läuftjaneinLäuft in-process?In nativem C++ schreibenVerwalteter Code ist in OrdnungCLR- / Wiedereintrittsrisiko macht den Host instabilVom Verb gestartete EXEOut-of-Process-Vorschau

Abbildung 9: Eine In-Process-Erweiterung ist in der Regel natives C++; verwalteter Code ist auf eine Konfiguration beschränkt, die in einem eigenen Prozess läuft.

5. Das neue Windows-11-Kontextmenü — das in zwei Teile gespaltene Menü

5.1. Was geschehen ist

Windows 11 hat das Kontextmenü des Datei-Explorers erneuert. Ausschneiden, Kopieren und Ähnliches wurden zu einer Zeile von Symbolen oben; „Öffnen“ und „Öffnen mit“ wurden oben zusammengefasst; und Befehle, die eine App hinzufügt, werden unter den Standardbefehlen der Shell gruppiert. Wenn eine App mehrere Befehle hinzufügt, werden sie in einem Flyout (Untermenü) mit dem Namen der App gesammelt.6

Und der entscheidende Punkt ist dieser. Klassische IContextMenu-basierte Shell-Erweiterungen wurden nicht gelöscht; sie wurden auf die Seite des alten Menüs verschoben, das mit „Weitere Optionen anzeigen“ (Umschalt+F10) öffnet und das Windows-10-Menü unverändert lädt.6 Die Identität der Eröffnungsberatung „das Menü wurde versteckt“ ist diese Spaltung.

Das Kontextmenü, das Windows 11 in zwei Teile gespalten hatWas beim Rechtsklick zuerst öffnet, ist das neue Menü; die einzigen Befehle, die dort erscheinen, sind solche, die mit IExplorerCommand und Paketidentität registriert sind; klassische IContextMenu-Erweiterungen werden ins alte Menü verschoben, das mit Weitere Optionen anzeigen öffnetWeitere Optionen anzeigen Umschalt+F10Rechtsklick auf eine DateiNeues Menü(Windows 11)IExplorerCommand- + IdentitätsbefehleAltes Menü(das Windows-10-Menü)Klassische IContextMenu-ErweiterungenMehrere Befehle werden in einem Flyout gesammelt

Abbildung 10: Die einzigen Befehle, die im neuen Menü erscheinen, sind IExplorerCommand- + Identitätsbefehle; klassische Erweiterungen werden auf die Seite des alten Menüs verschoben.

5.2. Der offizielle Weg ins neue Menü — IExplorerCommand + Manifestregistrierung

Es gibt eine Weise, einen eigenen Befehl ins neue Menü zu setzen. Bereiten Sie eine native DLL vor, die die Schnittstelle IExplorerCommand implementiert, und deklarieren Sie den COM-Server und die Kontextmenüerweiterung in einem MSIX-Paketmanifest.7

<!-- Paketmanifest (Auszug) -->
<com:Extension Category="windows.comServer">
  <com:ComServer>
    <com:SurrogateServer DisplayName="Komura commands">
      <com:Class Id="01234567-89AB-CDEF-0123-456789ABCDEF"
                 Path="KomuraCommand.dll" ThreadingModel="STA" />
    </com:SurrogateServer>
  </com:ComServer>
</com:Extension>
<desktop4:Extension Category="windows.fileExplorerContextMenus">
  <desktop4:FileExplorerContextMenus>
    <desktop5:ItemType Type=".kmrpt">
      <desktop5:Verb Id="VerifyReport"
                     Clsid="01234567-89AB-CDEF-0123-456789ABCDEF" />
    </desktop5:ItemType>
  </desktop4:FileExplorerContextMenus>
</desktop4:Extension>

Das Type von ItemType kann eine bestimmte Erweiterung angeben, oder * (alle Dateien), Directory (Ordner) oder Directory\Background (ein Ordnerhintergrund). Stimmen Sie die DLL auf die Architektur des Explorers ab (64-Bit / ARM64).7

IExplorerCommand selbst ist eine Schnittstelle, die seit der Windows-7-Ära existiert; Sie implementieren den Titel (GetTitle), das Symbol (GetIcon), den Zustand aktiviert / deaktiviert / ausgeblendet (GetState) und die Ausführung (Invoke). Die Methoden werden vom UI-Thread aufgerufen, also ist der Zugriff auf Netzwerkressourcen verboten, und Methoden zum Menüaufbau müssen schnell zurückkehren. Schwere Arbeit nach Invoke.147

Manifeststruktur einer Registrierung im neuen MenüDie COM-Server-Deklaration des MSIX-Manifests mappt eine CLSID auf eine DLL, und die Kontextmenüerweiterungsdeklaration bindet Ziel und Implementierung mit ItemType und Verb, sodass ein eigener Befehl im neuen Menü erscheintmappt CLSID auf DLLgibt mit ItemType und Verb anMSIX-ManifestCOM-Server-DeklarationMenüerweiterungsdeklarationIExplorerCommand-Implementierungs-DLLBefehl erscheint im neuen MenüDas Ziel ist eine Erweiterung, alle Dateien und Ähnliches

Abbildung 11: Zwei Deklarationen im Manifest binden die Implementierungs-DLL an das Ziel, und der Befehl erscheint im neuen Menü.

5.3. Die Option für eine nicht verpackte App — Identität allein mit einem Sparse-Paket holen

Die Notluke, wenn „unsere App kann nur als MSI verteilt werden; MSIX ist unmöglich“, ist ein Sparse-Paket (MSIX mit externem Speicherort). Sie signieren ein kleines MSIX, das nur ein Manifest ist, ohne App-Rumpf, und registrieren es am Ende des vorhandenen Installationsprogramms. Die App erwirbt dann Paketidentität, und die Manifestregistrierung oben (= Erscheinen im neuen Menü) wird möglich. Es ist ab Windows 10 Version 2004 verfügbar, und das Paket braucht eine Signatur mit einem Zertifikat, dem auf dem Zielrechner vertraut wird.8

Der Ablauf, Identität mit einem Sparse-Paket zu holenNachdem das vorhandene Installationsprogramm den App-Rumpf abgelegt hat, gibt die Registrierung eines nur-Manifest-Sparse-Pakets mit einem externen Speicherort der App Paketidentität und macht die Manifestregistrierung des neuen Menüs möglichVorhandenes InstallationsprogrammApp-Rumpf ablegenSparse-PaketNur Manifest, kein RumpfMit externem Speicherort registrierenPaketidentität erwerbenRegistrierung im neuen Menü wird möglichEine vertrauenswürdige Signatur ist nötig

Abbildung 12: Registrieren Sie ein Sparse-Paket ohne Rumpf mit einem externen Speicherort, und die App erwirbt Paketidentität.

Der größte Vorteil ist, dass Sie das Installationsprogramm nicht ersetzen müssen; es ist die realistische Antwort für eine App, die bereits ein MSI-/EXE-Installationsprogramm-Asset hat. Zum Vergleich mit einem vollständigen Umzug auf MSIX siehe auch „Windows-App-Verteilung wählen – MSI/MSIX/ClickOnce/xcopy/eigener Updater“.

5.4. Wie Zuordnungsverben im neuen Menü erscheinen

Ein Punkt, der leicht missverstanden wird: die Zuordnungen der Kapitel 2 und 3 (ProgID und Verb) leben im neuen Menü noch. Das Standardverb beim Doppelklick, „Öffnen“ und die „Öffnen mit“-Kandidaten werden aus der Zuordnung aufgelöst und oben im neuen Menü angezeigt. Wenn Sie also nur „mit dieser App öffnen können“ wollen, braucht Windows 11 keine Extraarbeit. Andererseits ist eine Zuordnung keine Allzweck-Menüerweiterung, sodass Sie für einen beliebigen eigenen Befehl in der ersten Schicht des neuen Menüs IExplorerCommand plus Identität brauchen — das ist die Rollenteilung.7

Die Rollenteilung zwischen Zuordnungen und neuem MenüEine ProgID-und-Verb-Zuordnung wird im neuen Menü noch genutzt, um das Standardverb, Öffnen und Öffnen mit aufzulösen, und wird oben angezeigt; einen beliebigen eigenen Befehl in die erste Schicht des neuen Menüs zu setzen erfordert IExplorerCommand und IdentitätZuordn.(ProgID + Verb)Standard / Öffnen auflösenOben im neuen MenüKeine Extraarbeit unter Win11Ein eigener BefehlIExplorerCommand+IdentitätErste Schicht des neuen Menüs

Abbildung 13: Zuordnungen erledigen im neuen Menü noch die Auflösung der „Öffnen“-Familie; nur ein eigener Befehl braucht IExplorerCommand plus Identität.

6. Eine praktische Entscheidungstabelle — welche der drei Optionen

Wir ordnen das Bisherige in eine praktische Dreiwege-Wahl.

Was Sie erreichen wollen Empfohlenes Mittel Aussehen unter Windows 11 Erforderliche Arbeit und Kosten
(a) Die interne App beim Doppelklick oder „Öffnen“ starten Zuordnung + statisches Verb (nur Registrierungsregistrierung) In „Öffnen“ und „Öffnen mit“ im neuen Menü integriert Nur Registrierungsregistrierung des Installationsprogramms. Keine DLL, keine Extra-Signaturanforderung
(b) Einen eigenen Befehl für die ausgewählte Datei/den ausgewählten Ordner ins neue Menü setzen IExplorerCommand-Implementierung + MSIX-Manifestregistrierung. Eine nicht verpackte App erhält Identität mit einem Sparse-Paket Erste Schicht des neuen Menüs (mehrere Befehle werden in einem App-Namen-Flyout gesammelt) Native C++-DLL + Paketidentität + Codesignatur
(c) Eine vorhandene klassische IContextMenu-Erweiterung weiter nutzen Vorerst so lassen (nicht für neue Entwicklung wählen) Nur Seite des alten Menüs, unter „Weitere Optionen anzeigen“ (Umschalt+F10) Einen 64-Bit-Build und die COM-Registrierung pflegen. Einen späteren Umzug nach (b) planen

Es gibt zwei Urteilspunkte. Erstens: holen Sie (b) oder (c) nicht für eine Anforderung, die (a) erfüllt. In dem Moment, in dem Sie eine Shell-Erweiterung schreiben, übernehmen Sie die Verantwortung für die Stabilität des Explorers. Zweitens: (c) ist nur „nicht kaputt“; als Benutzererlebnis bleibt es einen Schritt schlechter. Je häufiger ein Befehl im Tagesbetrieb genutzt wird, desto größer die Rendite eines Umzugs nach (b).

Wie Sie unter den drei Optionen wählenWenn Sie nur den Start beim Doppelklick oder Öffnen wollen, reichen eine Zuordnung und ein statisches Verb; um einen eigenen Befehl ins neue Menü zu setzen, nutzen Sie IExplorerCommand und MSIX-Manifestregistrierung; wenn Sie nicht MSIX werden können, vergeben Sie Identität mit einem Sparse-Paket; behalten Sie eine vorhandene klassische IContextMenu-Erweiterung vorerst auf der Seite des alten MenüsjaneinjajaneinneinReicht Öffnen?Zuordn. + statisches VerbEigener Befehl im neuen Menü?Können Sie MSIX werden?IExplorerCommand+MSIXSparse-Pkg-IdentitätKlassisches vorerst behaltenNur Seite des alten MenüsKeine DLL, kleines Risiko

Abbildung 14: Wählen Sie unter einem statischen Verb, IExplorerCommand plus Identität und dem Behalten des Klassischen je nach Anforderung.

7. Bereitstellung und Registrierung in der Praxis — Installationsprogramm, Sparse-Paket, Aufräumen

7.1. HKLM oder HKCU

Stimmen Sie es auf die Form des Installationsprogramms ab. Alle Benutzer (unter Program Files abgelegt, Administratorrechte) ist HKLM\Software\Classes; Pro-Benutzer-Installation (keine Erhöhung) ist HKCU\Software\Classes. Mischen Sie sie, und Sie erzeugen die Anfrage der Art „A kann es öffnen, aber B nicht“. Für eine Shell-Erweiterung, die CLSID-Registrierung betrifft, ist Reg-Free COM — das die Registrierungsregistrierung selbst überflüssig macht — eine gültige Option für COM-Nutzung in der App, lässt sich aber nicht auf eine Shell-Erweiterung anwenden, die der Explorer lädt, daher brauchen Sie die direkte Registrierung („Was ist Reg-Free COM - COM ohne Registrierung nutzen“).

7.2. Nach einer Änderung benachrichtigen — SHChangeNotify

Nachdem Sie eine Zuordnung registriert, geändert oder gelöscht haben, benachrichtigen Sie das Ereignis SHCNE_ASSOCCHANGED mit SHChangeNotify. Überspringen Sie das, und der Explorer kann die Änderung bis zu einem Neustart übersehen.110

// Nach dem Ändern von Zuordnungen einmal aufrufen, z. B. aus einer Installationsprogramm-Custom-Action
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);

7.3. Ein Sparse-Paket registrieren und entfernen

Das Registrieren und Entfernen eines Sparse-Pakets ist die Aufgabe des Installationsprogramms. Registrieren Sie nach dem Ablegen der Dateien; entfernen Sie vor dem Löschen der Dateien.8

# Zur Installationszeit: nach dem Ablegen der Dateien den Installationsordner als externen Speicherort registrieren
Add-AppxPackage -Path "C:\Program Files\KomuraSoft\KomuraReport.identity.msix" `
                -ExternalLocation "C:\Program Files\KomuraSoft"

# Zur Deinstallationszeit: die Paketregistrierung entfernen, bevor die Dateien gelöscht werden
Remove-AppxPackage <package full name>

Ein Punkt zum Beobachten: Add-AppxPackage registriert für den Benutzer, der es ausgeführt hat. Wenn Sie es aus einer Custom Action eines Per-Machine-MSI unter LocalSystem aufrufen, vergibt das dem installierenden Benutzer keine Identität, daher konfigurieren Sie es so, dass es unter Benutzerimitation läuft. Selbst dann gilt die Registrierung unter Imitation nur für den Benutzer, der diese Installation ausgeführt hat. Auf einem PC, den mehrere Benutzer nutzen, haben andere Benutzer und später angelegte Benutzer keine Paketidentität, und der Befehl erscheint nicht im neuen Menü. Damit jeder Benutzer es nutzt, stellen Sie einen Mechanismus bereit, etwa beim ersten Start die eigene Paketregistrierung zu prüfen und zu registrieren, falls sie fehlt (Pro-Benutzer-Registrierung), und nehmen Sie das Entfernen von jedem Benutzer, der eine Registrierung hat, in den Deinstallationsplan auf. Das Widerspiegeln einer Manifestregistrierung kann auch einen Explorer-Neustart (oder eine Abmeldung) erfordern.7

Reihenfolge beim Registrieren und Entfernen eines Sparse-PaketsZur Installationszeit registrieren Sie das Sparse-Paket nach dem Ablegen der Dateien; zur Deinstallationszeit entfernen Sie die Registrierung vor dem Löschen der Dateien; beachten Sie, dass die Registrierung nur für den Benutzer gilt, der sie ausgeführt hatInstallationDateien ablegenSparse-Paket registrierenDeinstallationPaketregistrierung entfernenDateien löschenRegistrierung gilt nur für den laufenden Benutzer

Abbildung 15: Registrieren Sie nach dem Ablegen der Dateien, entfernen Sie vor dem Löschen, und beachten Sie, dass die Registrierung pro laufendem Benutzer gilt.

7.4. Aufräumen bei der Deinstallation — was löschen und was lassen

Das Aufräumen bei der Deinstallation hat eine klare offizielle Anleitungslinie.1

  • Löschen: den ganzen internen ProgID-Schlüssel, die Capabilities-/RegisteredApplications-Registrierung, die CLSID-Registrierung der Shell-Erweiterung, das Sparse-Paket (Remove-AppxPackage).
  • Lassen: den Standardwert des Erweiterungsschlüssels (.kmrpt). Die offizielle Empfehlung ist, ihn nicht zu löschen, selbst wenn er noch auf die interne ProgID zeigt. Nach der Installation zu beurteilen, ob eine andere App die Vorgabe übernommen hat, ist schwierig, und Windows ignoriert einfach eine Standardwert-ProgID, die nicht registriert ist, sodass das Lassen keinen echten Schaden anrichtet.
  • Rufen Sie SHChangeNotify(SHCNE_ASSOCCHANGED) auch am Ende des Aufräumens auf.

Die meisten Probleme „wir haben deinstalliert und Reste erscheinen noch im Menü“ sind ein Leck in diesem Aufräumen-Entwurf.

Aufräumen-Entwurf bei der DeinstallationBei der Deinstallation löschen Sie den internen ProgID-Schlüssel, die CLSID-Registrierung und das Sparse-Paket; lassen Sie den Standardwert des Erweiterungsschlüssels, weil eine nicht registrierte ProgID ignoriert wird; benachrichtigen Sie die Änderung am Ende des Aufräumens mit SHChangeNotifyDeinstallationLöschenLassenProgID- und CLSID-RegistrierungSparse-PaketStandardwert des ErweiterungsschlüsselsEine nicht registrierte ProgID wird ignoriertAm Ende mit SHChangeNotify benachrichtigen

Abbildung 16: Löschen Sie die interne Registrierung, lassen Sie den Standardwert des Erweiterungsschlüssels, und benachrichtigen Sie die Änderung am Ende des Aufräumens.

8. Fehlerbehebung — fehlend, doppelt, schwer

8.1. Es erscheint nicht im Menü

Isolieren Sie in dieser Reihenfolge.

  1. Welches Menü Sie ansehen: Eine Registrierung im klassischen Stil erscheint nur auf der Seite des alten Menüs unter Umschalt+F10. Prüfen Sie zuerst beide.
  2. Bittigkeit: Eine nur-32-Bit-Shell-Erweiterungs-DLL wird nicht in den 64-Bit-Explorer geladen (Abschnitt 4.3).
  3. Registrierungsziel: HKLM/HKCU, eine Wow6432Node-Verwechslung. Bestätigen Sie den tatsächlichen Schlüssel mit reg query.
  4. Paketregistrierung: Für das neue Menü bestätigen Sie die Anwesenheit mit Get-AppxPackage, das Vertrauen des Signaturzertifikats und den -ExternalLocation-Pfad, dann starten Sie den Explorer neu.7
  5. Vergessene Benachrichtigung: Wenn SHChangeNotify vergessen wurde, können Sie es daran erkennen, ob ein Explorer-Neustart es wirksam macht.
Isolationsreihenfolge, wenn es nicht im Menü erscheintBeginnen Sie damit zu bestätigen, welches Menü Sie ansehen, isolieren Sie dann DLL-Bittigkeit, Registrierungsziel, Paketregistrierung und Signatur sowie ein vergessenes SHChangeNotify, in dieser ReihenfolgeBestätigen, welches Menü, alt oder neuDLL-Bittigkeit bestätigenHKLM- und HKCU-Registrierungsziel bestätigenPaketregistrierung und Signatur bestätigenEine vergessene Benachrichtigung am Neustart erkennen

Abbildung 17: Wenn es „nicht erscheint“, isolieren Sie in der Reihenfolge Menü, das Sie ansehen, Bittigkeit, Registrierungsziel, Paketregistrierung, vergessene Benachrichtigung.

8.2. Es erscheint doppelt oder geht nicht weg

Typische Ursachen sind die Koexistenz einer klassischen Registrierungsregistrierung und einer Manifestregistrierung, ein Leck im Deinstallations-Aufräumen (Abschnitt 7.4) oder Reste einer alten-Version-ProgID. Erscheint es nur im alten Menü doppelt, denken Sie an Reste; erscheint es auf alt und neu, denken Sie an Koexistenz.

Eine Doppelanzeige isolierenZweimal nur im alten Menü deutet auf Reste wie ein Aufräumen-Leck oder eine alte ProgID; zweimal auf alt und neu deutet auf die Koexistenz einer klassischen Registrierungsregistrierung und einer Manifestregistrierungnur altes Menüalt und neuAuf welchem erscheint es doppelt?ResteKoexistenzAufräumen-Leck oder eine hinterlassene alte ProgIDKlassische Registrierungsregistrierung koexistiert mit der neuen

Abbildung 18: Zweimal nur im alten Menü deutet auf Reste; zweimal auf alt und neu deutet auf Koexistenz.

8.3. Der Explorer ist schwer oder stürzt ab

Wenn ein Rechtsklick langsam ist oder ein bestimmter Ordner abstürzt, inventarisieren Sie zuerst die installierten Shell-Erweiterungen. Listen Sie Nicht-Microsoft-Erweiterungen mit einem Werkzeug wie NirSofts ShellExView, deaktivieren Sie die verdächtigen vorübergehend und identifizieren Sie die Täter-DLL per binärer Suche. Bei einem Absturz ist das „Faulting module“ der Ereignisanzeige ebenfalls ein Hinweis. War die interne Erweiterung die Ursache, verdächtigen Sie synchrone E/A oder Netzwerkzugriff auf dem Menüaufbaupfad (Abschnitte 4.2 und 5.2).

Die Täter-DLL identifizieren, wenn es schwer ist oder abstürztListen Sie Nicht-Microsoft-Shell-Erweiterungen in ShellExView, deaktivieren Sie die verdächtigen vorübergehend und identifizieren Sie die Täter-DLL per binärer Suche; bei einem Absturz ist das Faulting module der Ereignisanzeige ebenfalls ein HinweisShell-Erweiterungen inventarisierenDie Nicht-Microsoft-auflistenVorübergehend deaktivieren und binär suchenDie Täter-DLL identifizierenBei einem AbsturzDas Faulting module prüfen

Abbildung 19: Deaktivieren Sie Nicht-Microsoft-Erweiterungen vorübergehend und suchen Sie binär; bei einem Absturz nutzen Sie auch die Ereignisanzeige.

8.4. Windows Sandbox ist zur Prüfung praktisch

Die Prüfung der Shell-Integration beruht darauf, „auf einer sauberen Umgebung installieren → bedienen → deinstallieren → Reste null“ zu bestätigen. Praktisch hier ist Windows Sandbox (Pro/Enterprise/Education): jeder Start bringt in wenigen Sekunden ein brandneues Einweg-Windows, sodass Sie Tests zur Installationsprogramm-Registrierung und zum Aufräumen beliebig oft fahren können. Schließen Sie es, und alles verschwindet, daher eignet es sich auch zur Untersuchung von Rest-Registrierung.15

9. Zusammenfassung

  • Dateizuordnung ist die Dreischichtstruktur „Erweiterungsschlüssel → ProgID → Verb“, und HKCR ist eine zusammengeführte Ansicht von HKLM-/HKCU-Classes. Nennen Sie das Schreibziel ausdrücklich, und setzen Sie %1 immer in Anführungszeichen.
  • Die Standard-App ist so entworfen, dass sie der Benutzer wählt, und kann nicht von einem Programm geändert werden. Die Aufgabe des Installationsprogramms ist, sich korrekt als Kandidat zu registrieren.
  • Eine klassische Shell-Erweiterung ist eine In-Process-COM-DLL, die in den Explorer geladen wird. Ein Absturz oder eine Verzögerung greift auf das Ganze über; 64-Bit ist erforderlich; verwalteter Code ist nicht unterstützt; die Implementierung in nativem C++ ist die Regel.
  • Unter Windows 11 ist das Kontextmenü in zwei Teile zerfallen. Einen eigenen Befehl ins neue Menü zu setzen erfordert IExplorerCommand plus ein MSIX-Manifest; klassisches IContextMenu wird auf die Seite „Weitere Optionen anzeigen“ verschoben.
  • Für eine App, die nicht MSIX werden kann, ist das Holen der Identität mit einem Sparse-Paket (MSIX mit externem Speicherort) die realistische Antwort.
  • Wenn Sie nur „mit dieser App öffnen“ wollen, reichen eine Zuordnung und ein statisches Verb immer noch. Vom einfachsten Mittel zu starten ist auch die offizielle Richtlinie.
  • Nach Registrierung, Änderung oder Löschung benachrichtigen Sie mit SHChangeNotify; bei der Deinstallation löschen Sie die ProgID, lassen aber den Standardwert des Erweiterungsschlüssels. Windows Sandbox ist zur Prüfung praktisch.

Wenn ein Windows-11-PC-Austausch Sie merken ließ, dass „das Menü versteckt wurde“, bestätigen Sie zuerst, welches von (a), (b) und (c) in der Entscheidungstabelle von Kapitel 6 es ist. Sie sollten den Umfang der Arbeit an Ort und Stelle abschätzen können.

Verwandte Artikel

Verwandte Beratungsbereiche

KomuraSoft LLC übernimmt Entwurf und Implementierung von Dateizuordnung, Kontextmenüs und Shell-Erweiterungen für Geschäftsanwendungen; das Ansteuern des neuen Windows-11-Kontextmenüs (Umzug zu IExplorerCommand, Einführung eines Sparse-Pakets); die Prüfung von Registrierung und Aufräumen eines vorhandenen Installationsprogramms; und die Ursachenuntersuchung, wenn der Explorer schwer ist oder abstürzt. Es ist in Ordnung, damit zu beginnen, was mit „dem Menü, das unter Weitere Optionen anzeigen versteckt wurde“ zu tun ist.

Quellen

  1. Microsoft Learn, File Types. Zur Struktur eines Erweiterungsschlüssels, der auf eine ProgID zeigt; OpenWithProgIds; die Teilung der Registrierung zwischen HKLM/HKCU\Software\Classes; das Aufrufen von SHChangeNotify(SHCNE_ASSOCCHANGED) nach einer Zuordnungsänderung; und das Löschen der ProgID bei der Deinstallation bei Belassen des Standardwerts des Erweiterungsschlüssels.  2 3 4 5

  2. Microsoft Learn, HKEY_CLASSES_ROOT Key. Dazu, dass HKEY_CLASSES_ROOT eine zusammengeführte Ansicht von HKLM\Software\Classes und HKCU\Software\Classes ist; benutzerseitige Definitionen Vorrang vor maschinenseitigen haben; und die Verteilungsregeln beim Schreiben.  2

  3. Microsoft Learn, Windows app defaults platform. Dazu, dass das Ändern der Standard-App so entworfen ist, dass es nur über die Systemeinstellungen-UI geschieht; Benutzerdaten verschleiert und von einem Filtertreiber (UCPD.sys) schreibgeschützt sind; die registrierungsbasierte Änderung nicht unterstützt ist; und in einer verwalteten Umgebung Gruppenrichtlinie / MDM-Richtlinie genutzt wird.  2

  4. Microsoft Learn, Working with Shell Extensions. Zu den Arten von Shell-Erweiterungshandlern; einer Erweiterung als In-Process-COM-DLL, die in den Explorer (und in Prozesse, die die Shell hosten) geladen wird, sodass ein Absturz oder Hänger auf den Explorer als Ganzes übergreift; der Registrierung mit ThreadingModel=Apartment; und dem Erwägen einer einfacheren Alternative vor einer Shell-Erweiterung.  2 3

  5. Microsoft Learn, Guidance for Implementing In-Process Extensions. Dazu, dass Microsoft eine In-Process-Shell-Erweiterungsimplementierung in verwaltetem Code nicht empfiehlt und nicht unterstützt; Gründe einschließlich CLR-Versionskollisionen, Wiedereintritt und nicht deterministischer Objektlebensdauer; und verwalteter Code für eine Out-of-Process-Erweiterung (einen Vorschauhandler oder einen Start von shell\verb\command) akzeptabel ist.  2 3

  6. Windows Developer Blog, Extending the Context Menu and Share Dialog in Windows 11. Zum Entwurf des neuen Windows-11-Kontextmenüs; der Erweiterung über IExplorerCommand plus App-Identität; dem Platzieren von „Öffnen“ und „Öffnen mit“ oben; dem Sammeln mehrerer Befehle in einem App-Namen-Flyout; und klassischen IContextMenu-Erweiterungen, die unter „Weitere Optionen anzeigen“ (Umschalt+F10) als Windows-10-Menü geladen werden.  2 3

  7. Microsoft Learn, Add a File Explorer context menu command to a packaged desktop app. Dazu, dass die Registrierung im neuen Windows-11-Kontextmenü mit einer IExplorerCommand-Implementierung plus windows.comServer plus einer desktop4:FileExplorerContextMenus-Manifestdeklaration geschieht; ItemType *, Directory oder Directory\Background angeben kann; die DLL-Architektur abzustimmen ist; Methoden zum Menüaufbau schnell zu halten sind; eine nicht verpackte App mit einem Sparse-Paket abgedeckt wird; ein Explorer-Neustart manchmal nötig ist, damit die Registrierung greift; und eine Dateizuordnung keine Allzweck-Menüerweiterung ist.  2 3 4 5 6 7 8

  8. Microsoft Learn, Grant package identity by packaging with external location. Zum Holen von Paketidentität durch Registrieren eines Pakets mit externem Speicherort (Sparse-Paket) ohne Änderung des vorhandenen Installationsprogramms; der Verfügbarkeit ab Windows 10 Version 2004; und Windows-Funktionen, die Identität erfordern (Kontextmenüregistrierung, Benachrichtigungen und Ähnliches), die nutzbar werden.  2 3

  9. Microsoft Learn, Choosing a Static or Dynamic Shortcut Menu Method. Zur Wahl der einfachsten statischen-Verb-Methode, die die Anforderungen erfüllt; IContextMenu als der mächtigsten, aber auch komplexesten und zur nicht empfohlenen Seite klassifizierten; und IExplorerCommand/IExplorerCommandState als der empfohlenen Methode.  2

  10. Microsoft Learn, SHChangeNotify function. Zur Erhebung des Ereignisses SHCNE_ASSOCCHANGED, das das System über eine Dateizuordnungsänderung benachrichtigt, und zur Nutzung, damit die Shell die Änderung merkt.  2

  11. Microsoft Learn, Application Registration. Dazu, dass die Registrierung einer ausführbaren Datei über den Unterschlüssel App Paths empfohlen wird; die Rolle des Unterschlüssels Applications; die Verbregistrierung über SystemFileAssociations; und die Priorität der ProgID und zugehöriger Informationen, wenn die Standard-App wechselt. 

  12. Microsoft Learn, Creating Shortcut Menu Handlers. Zur Registrierung eines statischen Verbs; der Reihenfolge, in der das Standardverb entschieden wird (Standardwert → erstes Verb → Open → Open With); Anzeigenamen von Standardverben, die das Betriebssystem liefert; erweiterten Verben über Extended; der Zuordnung mit DDE-Befehlen, die Deprecated ist; und WOW64-Umleitungs-Fallstricken in einer 64-Bit-Umgebung.  2 3

  13. Microsoft Learn, Verbs and File Associations. Dazu, dass ein Verb eine Aktion ist, die auch von ShellExecuteEx genutzt wird; Elemente einer Befehlszeichenfolge, die ein Leerzeichen enthalten können, in Anführungszeichen gesetzt werden müssen und “%1” immer quoted geschrieben wird; und die Registrierung einer Standardprozedur unter HKCR\Applications. 

  14. Microsoft Learn, IExplorerCommand interface. Zur Methodenzusammensetzung von GetTitle, GetIcon, GetState, Invoke, EnumSubCommands und Ähnlichem; Methoden, die auf dem UI-Thread aufgerufen werden und daher nicht mit Netzwerkressourcen kommunizieren dürfen; und der Verfügbarkeit ab Windows Vista. 

  15. Microsoft Learn, Windows Sandbox. Dazu, ein wegwerfbares, isoliertes Windows in wenigen Sekunden starten zu können, alle Änderungen beim Schließen verworfen werden, es sich für Softwaretests und Installationsprogrammprüfung eignet, und es auf Pro/Enterprise/Education verfügbar ist. 

Aktuelle Artikel mit denselben Schlagwörtern führen zu verwandten Themen weiter.

Diese Seiten ordnen den Artikel in einen größeren Leistungs- und Entscheidungskontext ein.

Dieser Artikel ist direkt mit den folgenden Leistungen verbunden.

Häufige Fragen

Fragen, die in Beratungen zu diesem Artikelthema häufig gestellt werden.

Warum erscheint der Kontextmenüeintrag unserer App unter Windows 11 nur unter „Weitere Optionen anzeigen“?
Weil unter Windows 11 das Kontextmenü des Datei-Explorers in zwei Schichten zerfallen ist, alt und neu. Im neuen Menü erscheinen nur Befehle, die die Schnittstelle IExplorerCommand implementieren und in einem MSIX-Paketmanifest registriert sind (= die eine Paketidentität haben). Klassische IContextMenu-basierte Shell-Erweiterungen wurden ins alte Menü verschoben, das Sie mit „Weitere Optionen anzeigen“ (Umschalt+F10) öffnen. Die Erweiterung selbst ist nicht kaputt, sie funktioniert vorerst weiter, aber wenn Sie sie im neuen Menü wollen, brauchen Sie eine Migration zu IExplorerCommand und entweder die Verpackung als MSIX oder die Vergabe der Identität mit einem Sparse-Paket.
Kann das Installationsprogramm unsere App als Standard-App für eine Datei festlegen (die App, die beim Doppelklick öffnet)?
Nein. Die Wahl der Standard-App ist so entworfen, dass sie der Benutzer trifft, und Windows unterstützt das Ändern der Standard-App von nirgendwo sonst als der Systemeinstellungen-UI. Die UserChoice-Informationen, die die Wahl jedes Benutzers halten, sind verschleiert, und ein Filtertreiber (UCPD.sys) schützt sie zusätzlich schreibend vor Apps. Was ein Installationsprogramm tun kann, ist, eine ProgID und Verben zu registrieren, sich zu OpenWithProgIds hinzuzufügen, damit es als Kandidat unter „Öffnen mit“ erscheint, und den Benutzer zur Seite Standard-Apps zu lenken. Die korrekte Implementierung ist nicht, die Vorgabe zu stehlen, sondern bereit zu sein, gewählt zu werden.
Darf ich eine Shell-Erweiterung in verwaltetem Code wie C# schreiben?
Microsoft hat klar gesagt, dass das Schreiben einer In-Process-Shell-Erweiterung (eines Kontextmenühandlers, eines Symbolhandlers und Ähnlichem) in verwaltetem Code nicht empfohlen und nicht unterstützt wird. Die Erweiterung wird in den Explorer und in den Prozess jeder App geladen, die einen gemeinsamen Dateidialog öffnet, sodass CLR-Versionskollisionen, Wiedereintritt und nicht deterministische Objektlebensdauer die Host-App instabil machen. Die Regel ist eine Implementierung in nativem C++. Eine normale EXE, die von einem Verb-Command gestartet wird, oder eine Out-of-Process-Erweiterung wie ein Vorschauhandler, der in einem eigenen Prozess läuft, ist in verwaltetem Code in Ordnung.
Was ist ein Sparse-Paket (MSIX mit externem Speicherort)?
Ein kleines MSIX-Paket, das keine App-Dateien enthält, nur ein Manifest (Identitätsinformationen). Für eine App, die auf gewöhnliche Weise mit einem vorhandenen Installationsprogramm (MSI, Inno Setup und Ähnliches) installiert wird, registrieren Sie es mit Add-AppxPackage -ExternalLocation auf den Installationsordner, und die App erwirbt Paketidentität und kann Funktionen nutzen, die Identität erfordern, etwa die Registrierung im neuen Windows-11-Kontextmenü und Toastbenachrichtigungen. Es ist ab Windows 10 Version 2004 verfügbar, und das Paket braucht eine Codesignatur, der auf dem Zielrechner vertraut wird. Es ist die realistische Option, wenn Sie die neue Menüunterstützung wollen, ohne die gesamte Verteilung auf MSIX umzustellen.
Was soll ich tun, wenn ein Kontextmenüeintrag doppelt erscheint oder nicht verschwindet?
Isolieren Sie zuerst die Ursache, indem Sie prüfen, auf welchem Menü er erscheint: dem neuen oder dem alten (Weitere Optionen anzeigen). Die typische Doppelanzeige ist, dass eine klassische Registrierungsregistrierung und eine MSIX-Manifestregistrierung koexistieren, oder dass eine ProgID- oder Erweiterungs-CLSID-Registrierung bei der Deinstallation zurückgeblieben ist. Nach dem Ändern von Zuordnungen verdächtigen Sie auch ein vergessenes SHChangeNotify(SHCNE_ASSOCCHANGED); direkt nach der Paketregistrierung ein vergessenes Explorer-Neustart. Wenn das immer noch nicht löst, deaktivieren Sie vorübergehend Nicht-Microsoft-Erweiterungen in ShellExView und identifizieren Sie die Täter-DLL per binärer Suche.

Autorenprofil

Profilseite des Artikelautors.

Go Komura

Geschäftsführer von KomuraSoft LLC

Spezialisiert auf Windows-Softwareentwicklung, technische Beratung und Fehleranalyse, insbesondere bei bestehenden Systemen und schwer reproduzierbaren Störungen.

Zurück zum Blog