L'integrazione con la shell di Windows oggi ── menu contestuali, associazioni di file e cosa è cambiato in Windows 11

· · Windows, Estensioni della shell, Menu contestuale, Associazione di file, COM, Windows 11, Esplora file, MSIX, Sviluppo Windows

Mi è stato chiesto: «abbiamo sostituito i PC con Windows 11 e il menu contestuale dell’app che ci avete costruito anni fa è scomparso». Ascoltando meglio, non era scomparso. Clic destro su un file, scegliere «Mostra altre opzioni» in fondo al menu, e il menu familiare compare esattamente come sempre. In altre parole, le voci di menu dell’app interna erano state nascoste di un clic più in dentro. Dal campo sentiamo «è un clic in più» e «sono aumentate le richieste di chi non trova la voce».

Non è un guasto né una configurazione sbagliata; è un cambio di progettazione di Windows 11. Il menu contestuale di Esplora file è diventato una struttura a due strati, vecchio e nuovo, e le condizioni per mettere una voce nel nuovo menu sono diventate una cosa del tutto diversa da prima.

Nel frattempo, il meccanismo di associazione file e di estensioni della shell sotto è ancora il vecchio mondo di COM e del registro. Una chiave di estensione punta a un ProgID, il verb del ProgID contiene una riga di comando, e un’estensione più elaborata gira come server COM in-process (DLL) caricato in Esplora risorse — quella struttura non è cambiata da più di vent’anni. Se non conoscete insieme il fondamento invariato e il menu che Windows 11 ha diviso in due, non potete isolare «il menu non compare», «è nascosto» o «compare due volte».

Questo articolo è rivolto al personale IT di piccole e medie imprese e agli sviluppatori Windows che curano app aziendali. Collega, in un solo quadro, la struttura a tre strati dell’associazione file, le cautele delle estensioni della shell classiche, come puntare al nuovo menu contestuale di Windows 11, e registrazione, pulizia e risoluzione dei problemi dell’installer.

1. Prima la conclusione

  • Il fondamento del menu contestuale e dell’associazione file è la struttura a tre strati del registro «chiave di estensione → ProgID → verb». La chiave di estensione è un puntatore a un ProgID, il ProgID è la sostanza, e shell\<verb>\command sotto di esso contiene la riga di comando.1
  • HKEY_CLASSES_ROOT (HKCR) non è un hive indipendente; è una vista unita di HKLM\Software\Classes e HKCU\Software\Classes. Scrivete la registrazione per tutti gli utenti in HKLM e quella per utente in HKCU, e trattate HKCR come sola lettura.2
  • L’app predefinita (quella che si apre con il doppio clic) è progettata perché la scelga l’utente, e un programma non può rubarla. Il sistema operativo protegge la scelta dell’utente; ciò che un installer può fare è registrarsi come candidato.3
  • Un’estensione della shell classica è una DLL COM in-process caricata in Esplora risorse. Un arresto anomalo o un ritardo dell’estensione si propaga a Esplora risorse nel suo insieme (e ad altre app che usano la shell); un ambiente a 64 bit richiede una DLL a 64 bit; e un’implementazione in codice gestito non è supportata.45
  • In Windows 11 il menu contestuale si è diviso in due. Gli unici comandi che compaiono nel nuovo menu sono quelle registrate con IExplorerCommand più identità di pacchetto; le estensioni IContextMenu classiche sono spostate nel vecchio menu sotto «Mostra altre opzioni» (Maiusc+F10).67
  • La via ufficiale per mettere un comando personalizzato nel nuovo menu è registrare una DLL nativa che implementa IExplorerCommand in un manifesto MSIX (desktop4:FileExplorerContextMenus). Un’app che non può diventare MSIX può ricevere solo l’identità con uno sparse package (MSIX con posizione esterna).78
  • Se tutto ciò che volete è «aprire con questa app», un’associazione e un verb statico bastano ancora. Non serve una DLL di estensione della shell, e Microsoft stessa dice chiaramente «scegliere il metodo più semplice che soddisfa i requisiti (un verb statico)».9
  • Dopo registrazione o modifica, notificate con SHChangeNotify(SHCNE_ASSOCCHANGED); alla disinstallazione eliminate il ProgID ma non eliminate il valore predefinito della chiave di estensione — questa è la guida ufficiale. L’integrazione con la shell include la progettazione della pulizia.110

In una frase: il mondo delle associazioni e dei verb è invariato; solo come si mostra il menu si è diviso in due in Windows 11. Di seguito lo percorriamo dal fondamento.

2. Come funziona l’associazione file — la struttura a tre strati chiave di estensione → ProgID → verb

2.1. Leggere la struttura a tre strati da un esempio

Cosa succede quando fate doppio clic su un file di una data estensione lo decidono tre strati di chiavi del registro.1

HKEY_CLASSES_ROOT
   .kmrpt                                  ← (1) Chiave di estensione
      (Default) = KomuraSoft.Report.1      ←     Un puntatore che nomina solo il ProgID
      OpenWithProgids
         KomuraSoft.Report.1               ←     Un candidato in «Apri con»
   KomuraSoft.Report.1                     ← (2) ProgID (la sostanza dell'associazione)
      (Default) = Komura Report document
      DefaultIcon
         (Default) = "C:\Program Files\KomuraSoft\Report.exe",0
      shell                                ← (3) Elenco dei verb
         open
            command
               (Default) = "C:\Program Files\KomuraSoft\Report.exe" "%1"
  • (1) La chiave di estensione (.kmrpt) punta solo a un nome ProgID come valore predefinito. Scrivere qui un comando direttamente è un errore.
  • (2) Il ProgID (KomuraSoft.Report.1) è la sostanza dell’associazione; contiene il nome visualizzato, l’icona e l’elenco dei verb.
  • (3) Un verb è un’azione come «apri» o «stampa», e il valore predefinito di shell\open\command è la riga di comando effettivamente avviata.

Questa separazione è il motivo per cui potete puntare più estensioni (.kmrpt e .kmrpt-file, per esempio) allo stesso ProgID, o scambiare il ProgID quando aggiornate l’app.

La struttura a tre strati dell'associazione fileLa chiave di estensione è un puntatore il cui valore predefinito nomina un ProgID; il ProgID è la sostanza che contiene nome visualizzato, icona ed elenco dei verb; e il valore predefinito di command sotto il verb è la riga di comando effettivamente avviatanomina il ProgID come predefinitoChiave di estensione .kmrptProgID KomuraSoft.Report.1verb(open e altri sotto shell)valore predefinito di commandReport.exe viene avviatoContiene anche il nome visualizzato e DefaultIcon

Figura 1: La chiave di estensione è un puntatore, il ProgID è la sostanza, e il command del verb è la riga di comando effettivamente avviata.

2.2. HKCR è una «vista unita» — dove scrivete cambia il significato

L’esempio sopra è mostrato sotto HKEY_CLASSES_ROOT (HKCR), ma HKCR non è una posizione di archiviazione fisica; è una vista unita di HKLM\Software\Classes e HKCU\Software\Classes. Se la stessa chiave esiste in entrambi, vince il lato HKCU.2

HKCR è una vista unitaHKCR è HKLM e HKCU Classes sovrapposti; se la stessa chiave esiste in entrambi, vince HKCU; scrivete la registrazione in HKLM o HKCU in modo esplicito e trattate HKCR come sola letturaHKLM\\Software\\Classes(tutti gli utenti)HKCR(vista unita)HKCU\\Software\\Classes(per utente)Se esiste la stessa chiave, vince HKCUTrattatelo come sola lettura(per conferma)

Figura 2: HKCR è come appaiono HKLM e HKCU Classes quando sono sovrapposti; nominate sempre l’uno o l’altro come destinazione di scrittura.

Destinazione di scrittura Significato Diritti richiesti
HKLM\Software\Classes Registrazione comune a tutti gli utenti Amministratore
HKCU\Software\Classes Registrazione solo per quell’utente Nessuno
Scrivere direttamente in HKCR Instradato a seconda di dove vive già la chiave esistente Dipende

In pratica, la scissione sicura è scrivere sempre la registrazione in HKLM o HKCU in modo esplicito, e trattare HKCR come sola lettura (per conferma). Vale anche la pena ordinare il rapporto con il reindirizzamento del registro WOW64. I dati di associazione direttamente sotto HKLM\Software\Classes come chiavi di estensione e ProgID sono condivisi tra le viste del registro a 32 bit e a 64 bit da Windows 7, quindi un installer a 32 bit che li scrive non fugge sul lato Wow6432Node. Alcune sottochiavi di registrazione COM come Classes\CLSID, invece, sono reindirizzate, e quando registrate un’estensione della shell (COM in-process) la scissione di scrittura 32 bit / 64 bit conta. I dettagli sono in «Registry 32-bit/64-bit Redirection and Virtualization Pitfalls — Wow6432Node and the “The Value I Wrote Isn’t There” Problem».

2.3. Registrazione sul lato app — App Paths, Applications, RegisteredApplications

Ci sono anche tre tipi di registrazione sul lato app, in coppia con il lato file (estensione e ProgID).11

  • App Paths (HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths): registrazione che consente a ShellExecuteEx di avviare solo con il nome del file eseguibile. Microsoft la raccomanda perché non dovete inquinare la variabile d’ambiente PATH.
  • Applications (HKCR\Applications\<app.exe>): definisce il modo predefinito di aprire quando un file arbitrario viene consegnato in «Apri con», e il nome visualizzato dell’app (FriendlyAppName).
  • RegisteredApplications + Capabilities: dichiara le estensioni e i tipi MIME che l’app può gestire, ed è la registrazione che la fa comparire come candidato nella pagina Impostazioni delle app predefinite di Windows.

La maggior parte delle consultazioni «la nostra app non compare nell’elenco delle app predefinite» sono casi in cui il ProgID è stato registrato e questa registrazione Capabilities è stata omessa.

I tre tipi di registrazione sul lato appLa registrazione sul lato app ha tre tipi — App Paths, Applications e RegisteredApplications — responsabili rispettivamente dell'avvio solo con il nome file, del modo predefinito di aprire in Apri con, e della comparsa nella pagina delle app predefiniteRegistrazione sul lato appApp PathsApplicationsRegisteredApplicationsAvvio solo con il nome filePredefinito in Apri conCompare nella pagina delle app predefiniteÈ richiesta una dichiarazione Capabilities

Figura 3: Ci sono tre tipi di registrazione sul lato app, e comparire come candidato delle app predefinite richiede una registrazione Capabilities.

2.4. L’app predefinita appartiene all’utente — protezione UserChoice

Scrivere un ProgID come valore predefinito della chiave di estensione non la rende da sola l’app predefinita. Il risultato della scelta esplicita dell’utente in «Apri con» e simili è conservato in HKCU\...\Explorer\FileExts\<extension>\UserChoice, e la risoluzione dell’associazione preferisce quel lato.

E il punto importante è che Windows non supporta il cambio programmatico dell’app predefinita. Le impostazioni dell’app predefinita sono progettate perché le faccia l’utente tramite l’interfaccia Impostazioni di sistema; i dati UserChoice sono offuscati, e un driver filtro (UCPD.sys) blocca le scritture dalle app. In un ambiente gestito, Criteri di gruppo / criterio MDM è il mezzo ufficiale.3

Che strumenti come SetUserFTA, che «imitano l’hash e lo riscrivono», siano stati usati è l’altro lato di questa protezione. Ciò che dovete mettere nell’installer di un’app interna non è rubare il predefinito, ma i tre (a) registrazione corretta del ProgID e dei verb, (b) aggiungersi a OpenWithProgIds, e (c) se serve, indirizzare alla pagina Impostazioni.

Risoluzione dell'app predefinita e protezione UserChoiceIl risultato di una scelta esplicita dell'utente è conservato in UserChoice e preferito nella risoluzione dell'associazione; UCPD.sys blocca le riscritture dalle app, quindi ciò che un installer può fare è registrarsi come candidato e indirizzare alla pagina ImpostazionipreferitoUCPD.sys la bloccaUserChoice(la scelta dell'utente)Risoluzione dell'associazioneValore predefinito della chiave di estensioneRiscrittura da un'appIl lavoro dell'installerRegistrare il ProgID e i verbAggiungere a OpenWithProgIdsIndirizzare alla pagina Impostazioni

Figura 4: La risoluzione dell’associazione preferisce la scelta dell’utente (UserChoice), e il sistema operativo la protegge dalle riscritture delle app.

3. Verb diversi da «Apri» — print, edit, runas, verb personalizzati

Un verb non è solo open. I verb standard di cui il sistema operativo conosce il significato includono edit, print, play e preview oltre a open, e un verb standard ottiene automaticamente un nome visualizzato che segue le impostazioni locali del sistema. Il verb predefinito usato al doppio clic è deciso nell’ordine: valore predefinito della chiave shell → primo verb nel registro → openopenwith.12

Ordine in cui si decide il verb predefinitoIl verb predefinito usato al doppio clic è il primo trovato nell'ordine valore predefinito della chiave shell, primo verb nel registro, open, openwithse nessunose nessunose nessunovalore predefinito della chiave shellPrimo verb nel registroopenopenwith

Figura 5: Il verb predefinito al doppio clic è il primo trovato in questo ordine.

Quando volete aggiungere un’azione vostra, registrate un verb personalizzato.

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                          ← verb personalizzato
         (Default) = Verify report (&V)   ← nome visualizzato nel menu
         command
            (Default) = "C:\Program Files\KomuraSoft\Report.exe" /verify "%1"

Tre piccoli fatti che aiuta conoscere.

  • Registrate un verb di nome runas e definite un avvio con elevazione equivalente a «Esegui come amministratore», usato anche quando un’API della famiglia ShellExecute specifica runas.
  • Mettete un valore vuoto di nome Extended sulla chiave del verb e diventa un verb esteso mostrato solo con Maiusc+clic destro. Comodo per nascondere un’operazione pericolosa usata di rado.12
  • Alcune associazioni di app più vecchie hanno ancora una configurazione che invia un documento in un processo esistente con DDE (la chiave ddeexec), ma avviare un verb via DDE è già un retaggio Deprecated. Non c’è motivo di scriverlo di nuovo.12

Un altro incidente frequente è le virgolette sulla riga di comando. Se un elemento della stringa di comando può contenere uno spazio, dovete avvolgerlo tra virgolette. Vale ovviamente per un percorso EXE come C:\Program Files\..., e %1 (il percorso del file selezionato) va sempre scritto "%1". Non potete garantire che il percorso di un file utente non contenga uno spazio. Un My Program.exe senza virgolette è interpretato come «avvia My con l’argomento Program.exe».13

L'incidente delle virgolette sulla riga di comandoUn comando senza virgolette viene spezzato allo spazio e frainteso come avvio di My con l'argomento Program.exe, quindi un percorso EXE che può contenere uno spazio e %1, che rappresenta il percorso del file selezionato, vanno sempre avvolti tra virgolettespezzato allo spazioComando senza virgoletteFrainteso come avvio di un altro EXEComando con virgoletteSi avvia come previstoAvvolgete il percorso EXE tra virgoletteAvvolgete sempre anche %1 tra virgolette

Figura 6: Un comando senza virgolette viene spezzato male allo spazio, quindi avvolgete sempre il percorso EXE e %1 tra virgolette.

Il meccanismo solo-registro finora (un verb statico) si può realizzare senza scrivere una sola DLL, e non rischia di rendere instabile Esplora risorse. Microsoft stessa ripete «prima di scrivere un’estensione della shell, considerate se il verb statico più semplice che soddisfa i requisiti basta».9

4. Estensioni della shell classiche — una DLL che gira dentro Esplora risorse

4.1. Tipi di estensione della shell

I requisiti che un verb statico non può soddisfare — «cambiare il menu in modo dinamico a seconda della selezione», «sostituire l’icona o il foglio proprietà» — usano un gestore di estensione della shell. I tipi rappresentativi sono i seguenti.4

Gestore Interfaccia principale Cosa può fare
Gestore di menu contestuale IContextMenu + IShellExtInit Aggiungere e controllare dinamicamente le voci di menu
Gestore di icone / overlay di icone IExtractIcon / IShellIconOverlayIdentifier Icona per file e overlay
Gestore di foglio proprietà IShellPropSheetExt Aggiungere una scheda al foglio proprietà
Miniatura / infotip IThumbnailProvider / IQueryInfo Vista miniatura e descrizione al passaggio
Gestore drag-and-drop / copy-hook IDropTarget / ICopyHook Intervenire al rilascio o a copia/spostamento

Tutti sono implementati come classi COM e registrati nel registro per CLSID. L’idea di COM in sé è in «COM, ActiveX e OCX — Distinzioni pratiche per chi eredita sistemi Windows».

4.2. Cosa significa essere un server COM in-process

L’essenza di un’estensione della shell classica è che è un server COM in-process (DLL) caricato in Esplora risorse (o in qualsiasi app che ha aperto una finestra di dialogo file comune). Ogni cautela ne consegue.4

  • Se l’estensione va in crash, Esplora risorse viene portato giù con essa. Se si blocca, un clic destro si congela per diversi secondi. Il danno non si limita a Esplora risorse; raggiunge ogni app che ha mostrato una finestra di apertura file.
  • La costruzione del menu avviene sul thread UI, quindi non dovete fare lavoro lento come accesso di rete o I/O di file al momento della visualizzazione del menu.
  • Registrate il modello di threading come Apartment di regola.
Struttura dei danni collaterali di un'estensione in-processUna DLL di estensione della shell viene caricata non solo in Esplora risorse ma anche nel processo di qualsiasi app che ha aperto una finestra di dialogo file, quindi un crash o un blocco dell'estensione si propaga a tutto il processo ospitecaricata in-processcaricata in-processDLL di estensione della shellEsplora risorseQualsiasi app che apre una finestra di dialogoUn crash o un blocco si propagaNon fare lavoro lento in visualizzazione

Figura 7: La DLL dell’estensione gira dentro il processo ospite, quindi un crash o un blocco si propaga all’ospite nel suo insieme.

Indagate una consultazione come «Esplora risorse si congela quando apro una cartella particolare» o «un clic destro impiega cinque secondi» e non è raro che la causa sia un’estensione della shell di terze parti piuttosto che l’app interna. I metodi di isolamento sono nel capitolo 8.

4.3. Allineare la bitness — un ambiente a 64 bit richiede una DLL a 64 bit

Una DLL in-process deve coincidere con la bitness del processo che la carica. Esplora risorse su Windows a 64 bit è un processo a 64 bit, quindi una DLL di estensione della shell compilata solo a 32 bit non viene mai caricata e non compare affatto nel menu. Non c’è nemmeno un errore, quindi è una causa classica di «l’ho registrata ma non compare». Combinare un corpo app a 32 bit con una DLL di estensione della shell a 64 bit è una configurazione legittima, ma dovete osservare il fatto che la registrazione COM si divide per bitness (Wow6432Node). L’avvio dal command di un verb è un EXE in processo separato, quindi non è soggetto a questo vincolo (lasciarlo un EXE a 32 bit va bene).

Allineare la bitness di una DLL di estensione della shellL'unica DLL di estensione della shell che Esplora risorse a 64 bit può caricare è una a 64 bit; una DLL solo a 32 bit non compare nel menu e non produce errore; un EXE avviato da un command di verb è un processo separato e non è soggetto al vincolopuò caricarenon può caricareprocesso separatoEsplora risorse a 64 bitDLL di estensione della shell a 64 bitDLL solo a 32 bitNon compare nel menu, senza erroreEXE avviato da un verbVa bene lasciato a 32 bit

Figura 8: L’unica DLL caricata in Esplora risorse a 64 bit è una DLL a 64 bit; un EXE avviato da un verb non è soggetto a questo vincolo.

4.4. Perché non dovete scriverla in codice gestito

Mi fanno spesso la domanda «posso scrivere un’estensione della shell in C#», ma Microsoft ha detto chiaramente che scrivere un’estensione della shell in-process in codice gestito (.NET) non è raccomandato ed è fuori dal supporto.5

Il motivo è la natura dell’estensione caricata in un processo arbitrario. Collisioni di versione del CLR (soprattutto sotto .NET Framework 4), il problema del CLR che rientra nel ciclo dei messaggi mentre attende un lock, e la durata degli oggetti non deterministica della garbage collection che collide con il contratto di conteggio dei riferimenti di COM sono ragioni strutturali per cui l’app ospite diventa instabile. Alcuni punti sono stati attenuati su .NET Framework 4 e successivi e sul .NET moderno, ma la posizione ufficiale non è cambiata.

La linea pratica è semplice. Scrivete un’estensione in-process in C++ nativo. Se volete usare codice gestito, fatene un EXE normale avviato dal command di un verb, o un’estensione out-of-process che gira in un processo separato (un gestore di anteprima e simili).5

Giudicare se il codice gestito è consentitoUn'estensione in-process che gira dentro Esplora risorse si scrive in C++ nativo di regola; se volete codice gestito, fatene un EXE normale avviato da un command di verb o un'estensione out-of-process che gira in un processo separatonoGira in-process?Scrivetela in C++ nativoIl codice gestito va beneRischio CLR / rientranza rende l'ospite instabileEXE avviato da un verbAnteprima out-of-process

Figura 9: Un’estensione in-process è C++ nativo di regola; il codice gestito è limitato a una configurazione che gira in un processo separato.

5. Il nuovo menu contestuale di Windows 11 — il menu diviso in due

5.1. Cosa è successo

Windows 11 ha rinnovato il menu contestuale di Esplora file. Taglia, copia e simili sono diventati una riga di icone in alto; «Apri» e «Apri con» sono stati raggruppati in alto; e i comandi che un’app aggiunge sono raggruppati sotto i comandi standard della shell. Quando un’app aggiunge più comandi, vengono raccolti in un flyout (sottomenu) con il nome dell’app.6

E il punto cruciale è questo. Le estensioni della shell classiche basate su IContextMenu non sono state eliminate; sono state spostate sul lato del vecchio menu che si apre con «Mostra altre opzioni» (Maiusc+F10) e carica il menu di Windows 10 così com’è.6 L’identità della consultazione iniziale «il menu è stato nascosto» è questa divisione.

Il menu contestuale che Windows 11 ha diviso in dueCiò che si apre per primo al clic destro è il nuovo menu; le uniche comandi che vi compaiono sono quelle registrate con IExplorerCommand e identità di pacchetto; le estensioni IContextMenu classiche sono spostate nel vecchio menu che si apre con Mostra altre opzioniMostra altre opzioni Maiusc+F10Clic destro su un fileNuovo menu(Windows 11)Comandi IExplorerCommand + identitàVecchio menu(il menu di Windows 10)Estensioni IContextMenu classichePiù comandi vengono raccolti in un flyout

Figura 10: Gli unici comandi che compaiono nel nuovo menu sono i comandi IExplorerCommand + identità; le estensioni classiche sono spostate sul lato del vecchio menu.

5.2. La via ufficiale nel nuovo menu — IExplorerCommand + registrazione nel manifesto

C’è un modo per mettere un comando personalizzato nel nuovo menu. Preparate una DLL nativa che implementa l’interfaccia IExplorerCommand, e dichiarate il server COM e l’estensione del menu contestuale in un manifesto di pacchetto MSIX.7

<!-- Manifesto del pacchetto (estratto) -->
<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>

Il Type di ItemType può specificare una particolare estensione, o * (tutti i file), Directory (cartelle) o Directory\Background (uno sfondo di cartella). Allineate la DLL all’architettura di Esplora risorse (64 bit / ARM64).7

IExplorerCommand stessa è un’interfaccia esistente dall’epoca di Windows 7; implementate il titolo (GetTitle), l’icona (GetIcon), lo stato abilitato / disabilitato / nascosto (GetState) e l’esecuzione (Invoke). I metodi sono chiamati dal thread UI, quindi l’accesso a risorse di rete è vietato, e i metodi di costruzione del menu devono tornare in fretta. Il lavoro pesante dopo Invoke.147

Struttura del manifesto di una registrazione nel nuovo menuLa dichiarazione del server COM del manifesto MSIX mappa un CLSID a una DLL, e la dichiarazione di estensione del menu contestuale lega destinazione e implementazione con ItemType e Verb, così un comando personalizzato compare nel nuovo menumappa il CLSID alla DLLspecifica con ItemType e VerbManifesto MSIXDichiarazione del server COMDichiarazione di estensione del menuDLL di implementazione IExplorerCommandIl comando compare nel nuovo menuLa destinazione è un'estensione, tutti i file e simili

Figura 11: Due dichiarazioni nel manifesto legano la DLL di implementazione alla destinazione, e il comando compare nel nuovo menu.

5.3. L’opzione per un’app non impacchettata — ottenere solo l’identità con uno sparse package

La via di fuga quando «la nostra app non può essere distribuita se non come MSI; MSIX è impossibile» è uno sparse package (MSIX con posizione esterna). Firmate un piccolo MSIX che è solo un manifesto, senza corpo dell’app, e lo registrate alla fine dell’installer esistente. L’app acquisisce allora identità di pacchetto, e la registrazione nel manifesto sopra (= comparsa nel nuovo menu) diventa possibile. È disponibile da Windows 10 versione 2004 in poi, e il pacchetto necessita di una firma con un certificato attendibile sulla macchina di destinazione.8

Il flusso per ottenere l'identità con uno sparse packageDopo che l'installer esistente ha collocato il corpo dell'app, registrare uno sparse package di solo manifesto con una posizione esterna dà all'app identità di pacchetto e rende possibile la registrazione nel manifesto del nuovo menuInstaller esistenteCollocare il corpo dell'appSparse packageSolo manifesto, nessun corpoRegistrare con una posizione esternaAcquisire identità di pacchettoLa registrazione nel nuovo menu diventa possibileÈ richiesta una firma attendibile

Figura 12: Registrate uno sparse package che non contiene il corpo, con una posizione esterna, e l’app acquisisce identità di pacchetto.

Il vantaggio maggiore è che non dovete sostituire l’installer; è la risposta realistica per un’app che ha già un asset di installer MSI/EXE. Per un confronto con un passaggio completo a MSIX, vedete anche «Scegliere un metodo di distribuzione per app Windows - MSI/MSIX/ClickOnce/xcopy/Updater personalizzato».

5.4. Come i verb di associazione compaiono nel nuovo menu

Un punto facile da fraintendere: le associazioni dei capitoli 2 e 3 (ProgID e verb) sono ancora vive nel nuovo menu. Il verb predefinito al doppio clic, «Apri» e i candidati «Apri con» sono risolti dall’associazione e mostrati in cima al nuovo menu. Quindi se tutto ciò che volete è «poter aprire con questa app», Windows 11 non richiede lavoro extra. D’altra parte, un’associazione non è un’estensione di menu per uso generale, quindi se volete un comando personalizzato arbitrario nel primo strato del nuovo menu serve IExplorerCommand più identità — questa è la divisione dei ruoli.7

La divisione dei ruoli tra associazioni e nuovo menuUn'associazione ProgID-e-verb è ancora usata nel nuovo menu per risolvere il verb predefinito, Apri e Apri con, ed è mostrata in cima; mettere un comando personalizzato arbitrario nel primo strato del nuovo menu richiede IExplorerCommand e identitàAssoc.(ProgID + verb)Risolvere predefinito / ApriCima del nuovo menuNessun lavoro extra su Win11Un comando personalizzatoIExplorerCommand+identitàPrimo strato del nuovo menu

Figura 13: Le associazioni gestiscono ancora la risoluzione della famiglia «Apri» nel nuovo menu; solo un comando personalizzato richiede IExplorerCommand più identità.

6. Una tabella di decisione pratica — quale delle tre opzioni prendere

Organizziamo quanto visto finora in una scelta pratica a tre vie.

Cosa volete ottenere Mezzo raccomandato Come appare in Windows 11 Lavoro e costo richiesti
(a) Avviare l’app interna al doppio clic o «Apri» Associazione + verb statico (solo registrazione nel registro) Integrato in «Apri» e «Apri con» nel nuovo menu Solo registrazione nel registro dell’installer. Nessuna DLL, nessun requisito extra di firma
(b) Mettere un comando personalizzato per il file/cartella selezionato nel nuovo menu Implementazione IExplorerCommand + registrazione nel manifesto MSIX. Un’app non impacchettata riceve identità con uno sparse package Primo strato del nuovo menu (più comandi raccolti in un flyout con il nome dell’app) DLL C++ nativa + identità di pacchetto + firma del codice
(c) Continuare a usare un’estensione IContextMenu classica esistente Tenerla com’è per ora (non sceglierla per un nuovo sviluppo) Solo lato del vecchio menu, sotto «Mostra altre opzioni» (Maiusc+F10) Mantenere una build a 64 bit e la registrazione COM. Pianificare un passaggio successivo a (b)

Ci sono due punti di giudizio. Primo, non portate (b) o (c) per un requisito che (a) soddisfa. Nel momento in cui scrivete un’estensione della shell vi assumete la responsabilità della stabilità di Esplora risorse. Secondo, (c) è solo «non rotto»; come esperienza utente resta un passo peggiore. Più un comando è usato di frequente nell’esercizio quotidiano, maggiore è il ritorno di un passaggio a (b).

Come scegliere tra le tre opzioniSe tutto ciò che volete è l'avvio al doppio clic o Apri, bastano un'associazione e un verb statico; per mettere un comando personalizzato nel nuovo menu usate IExplorerCommand e la registrazione nel manifesto MSIX; se non potete diventare MSIX, concedete l'identità con uno sparse package; tenete un'estensione IContextMenu classica esistente sul lato del vecchio menu per oranononoBasta Apri?Assoc. + verb staticoPersonalizzato nel nuovo menu?Potete diventare MSIX?IExplorerCommand+MSIXIdentità sparse-pkgTenere il classico per oraSolo lato del vecchio menuNessuna DLL, rischio piccolo

Figura 14: Scegliete tra un verb statico, IExplorerCommand più identità e il tenere il classico, secondo il requisito.

7. Distribuzione e registrazione in pratica — installer, sparse package, pulizia

7.1. HKLM o HKCU

Allineatelo alla forma dell’installer. Tutti gli utenti (collocato sotto Program Files, diritti di amministratore) è HKLM\Software\Classes; installazione per utente (senza elevazione) è HKCU\Software\Classes. Mischiateli e produce la richiesta del tipo «A può aprirlo ma B no». Per un’estensione della shell che implica registrazione CLSID, Reg-Free COM — che elimina il bisogno della registrazione nel registro stessa — è un’opzione valida per l’uso COM in-app, ma non si può applicare a un’estensione della shell che Esplora risorse carica, quindi serve la registrazione frontale («Cos’è Reg-Free COM - Utilizzo di COM senza registrazione»).

7.2. Dopo una modifica, notificate — SHChangeNotify

Dopo aver registrato, modificato o eliminato un’associazione, notificate l’evento SHCNE_ASSOCCHANGED con SHChangeNotify. Saltate questo e Esplora risorse può non accorgersi della modifica fino a un riavvio.110

// Chiamare una volta dopo aver modificato le associazioni, p. es. da un'azione personalizzata dell'installer
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);

7.3. Registrare e rimuovere uno sparse package

Registrare e rimuovere uno sparse package è il lavoro dell’installer. Registrate dopo aver collocato i file; rimuovete prima di eliminare i file.8

# In installazione: dopo aver collocato i file, registrare la cartella di installazione come posizione esterna
Add-AppxPackage -Path "C:\Program Files\KomuraSoft\KomuraReport.identity.msix" `
                -ExternalLocation "C:\Program Files\KomuraSoft"

# In disinstallazione: rimuovere la registrazione del pacchetto prima di eliminare i file
Remove-AppxPackage <package full name>

Un punto da osservare: Add-AppxPackage registra per l’utente che l’ha eseguito. Se lo chiamate da un’azione personalizzata di un MSI per macchina, eseguirlo sotto LocalSystem non concede identità all’utente che ha installato, quindi lo configurate per girare sotto impersonation dell’utente. Anche allora, la registrazione sotto impersonation è solo per l’utente che ha eseguito quella installazione. Su un PC usato da più utenti, gli altri utenti e gli utenti creati dopo non hanno identità di pacchetto, e il comando non compare nel nuovo menu. Perché ogni utente lo usi, fornite un meccanismo come controllare la propria registrazione del pacchetto al primo avvio e registrare se manca (registrazione per utente), e includete la rimozione da ogni utente che ha una registrazione nel piano di disinstallazione. Riflettere una registrazione nel manifesto può anche richiedere un riavvio di Esplora risorse (o una disconnessione).7

Ordine di registrazione e rimozione di uno sparse packageIn installazione registrate lo sparse package dopo aver collocato i file; in disinstallazione rimuovete la registrazione prima di eliminare i file; osservate il fatto che la registrazione è efficace solo per l'utente che l'ha eseguitaInstallazioneCollocare i fileRegistrare lo sparse packageDisinstallazioneRimuovere la registrazione del pacchettoEliminare i fileLa registrazione è efficace solo per l'utente in esecuzione

Figura 15: Registrate dopo aver collocato i file, rimuovete prima di eliminarli, e osservate il fatto che la registrazione è per utente in esecuzione.

7.4. Pulizia alla disinstallazione — cosa eliminare e cosa lasciare

La pulizia alla disinstallazione ha una linea di guida ufficiale chiara.1

  • Eliminare: l’intera chiave ProgID interna, la registrazione Capabilities/RegisteredApplications, la registrazione CLSID dell’estensione della shell, lo sparse package (Remove-AppxPackage).
  • Lasciare: il valore predefinito della chiave di estensione (.kmrpt). La raccomandazione ufficiale è di non eliminarlo anche se punta ancora al ProgID interno. Giudicare dopo l’installazione se un’altra app ha preso il predefinito è difficile, e Windows ignora semplicemente un ProgID di valore predefinito che non è registrato, quindi lasciarlo non fa un danno reale.
  • Chiamate SHChangeNotify(SHCNE_ASSOCCHANGED) anche alla fine della pulizia.

La maggior parte dei problemi «abbiamo disinstallato e i resti compaiono ancora nel menu» è una perdita in questa progettazione della pulizia.

Progettazione della pulizia alla disinstallazioneAlla disinstallazione eliminate la chiave ProgID interna, la registrazione CLSID e lo sparse package; lasciate il valore predefinito della chiave di estensione perché un ProgID non registrato viene ignorato; notificate la modifica con SHChangeNotify alla fine della puliziaDisinstallazioneEliminareLasciareRegistrazione ProgID e CLSIDSparse packageValore predefinito della chiave di estensioneUn ProgID non registrato viene ignoratoNotificare con SHChangeNotify alla fine

Figura 16: Eliminate la registrazione interna, lasciate il valore predefinito della chiave di estensione e notificate la modifica alla fine della pulizia.

8. Risoluzione dei problemi — mancante, duplicato, pesante

8.1. Non compare nel menu

Isolate in questo ordine.

  1. Quale menu state guardando: una registrazione in stile classico compare solo sul lato del vecchio menu sotto Maiusc+F10. Controllate entrambi prima.
  2. Bitness: una DLL di estensione della shell solo a 32 bit non viene caricata in Esplora risorse a 64 bit (sezione 4.3).
  3. Destinazione di registrazione: HKLM/HKCU, una confusione Wow6432Node. Confermate la chiave reale con reg query.
  4. Registrazione del pacchetto: per il nuovo menu, confermate la presenza con Get-AppxPackage, l’attendibilità del certificato di firma e il percorso -ExternalLocation, poi riavviate Esplora risorse.7
  5. Notifica dimenticata: se SHChangeNotify è stato dimenticato, potete dirlo da se un riavvio di Esplora risorse lo fa entrare in vigore.
Ordine di isolamento quando non compare nel menuIniziate confermando quale menu state guardando, poi isolate la bitness della DLL, la destinazione di registrazione nel registro, la registrazione del pacchetto e la firma, e una notifica SHChangeNotify dimenticata, in quest'ordineConfermare quale menu, vecchio o nuovoConfermare la bitness della DLLConfermare la destinazione di registrazione HKLM e HKCUConfermare registrazione del pacchetto e firmaDire una notifica dimenticata riavviando

Figura 17: Quando «non compare», isolate nell’ordine menu che state guardando, bitness, destinazione di registrazione, registrazione del pacchetto, notifica dimenticata.

8.2. Compare due volte, o non scompare

Le cause tipiche sono la coesistenza di una registrazione classica nel registro e di una registrazione nel manifesto, una perdita nella pulizia della disinstallazione (sezione 7.4) o resti di un ProgID di versione precedente. Se compare due volte solo nel vecchio menu, pensate a resti; se compare su vecchio e nuovo, pensate a coesistenza.

Isolare una doppia visualizzazioneDue volte solo nel vecchio menu punta a resti come una perdita di pulizia o un vecchio ProgID; due volte su vecchio e nuovo punta alla coesistenza di una registrazione classica nel registro e di una registrazione nel manifestosolo vecchio menuvecchio e nuovoSu quale compare due volte?RestiCoesistenzaPerdita di pulizia o un vecchio ProgID rimastoRegistrazione classica nel registro che coesiste con la nuova

Figura 18: Due volte solo nel vecchio menu punta a resti; due volte su vecchio e nuovo punta a coesistenza.

8.3. Esplora risorse è pesante o va in crash

Quando un clic destro è lento, o una cartella particolare va in crash, fate prima l’inventario delle estensioni della shell installate. Elencate le estensioni non Microsoft con uno strumento come ShellExView di NirSoft, disabilitate temporaneamente quelle sospette e identificate la DLL colpevole con una ricerca binaria. In un crash, il «Faulting module» del Visualizzatore eventi è anche un indizio. Se l’estensione interna era la causa, sospettate I/O sincrono o accesso di rete sul percorso di costruzione del menu (sezioni 4.2 e 5.2).

Identificare la DLL colpevole quando è pesante o va in crashElencate le estensioni della shell non Microsoft in ShellExView, disabilitate temporaneamente quelle sospette e identificate la DLL colpevole con una ricerca binaria; in un crash, il faulting module del Visualizzatore eventi è anche un indizioInventariare le estensioni della shellElencare quelle non MicrosoftDisabilitare temporaneamente e ricerca binariaIdentificare la DLL colpevoleIn un crashControllare il faulting module

Figura 19: Disabilitate temporaneamente le estensioni non Microsoft e fate una ricerca binaria; in un crash usate anche il Visualizzatore eventi.

8.4. Windows Sandbox è comodo per la verifica

La verifica dell’integrazione con la shell si basa sul confermare «installare su un ambiente pulito → operare → disinstallare → resti zero». Comodo qui è Windows Sandbox (Pro/Enterprise/Education): ogni avvio porta in pochi secondi un Windows usa-e-getta nuovissimo, quindi potete eseguire i test di registrazione e pulizia dell’installer quante volte volete. Chiudetelo e tutto scompare, quindi va anche per l’indagine del registro residuo.15

9. Riassunto

  • L’associazione file è la struttura a tre strati «chiave di estensione → ProgID → verb», e HKCR è una vista unita di HKLM/HKCU Classes. Nominate la destinazione di scrittura in modo esplicito e avvolgete sempre %1 tra virgolette.
  • L’app predefinita è progettata perché la scelga l’utente e non si può cambiare da un programma. Il lavoro dell’installer è registrarsi correttamente come candidato.
  • Un’estensione della shell classica è una DLL COM in-process caricata in Esplora risorse. Un crash o un ritardo si propaga al tutto; servono 64 bit; il codice gestito non è supportato; l’implementazione in C++ nativo è la regola.
  • In Windows 11 il menu contestuale si è diviso in due. Mettere un comando personalizzato nel nuovo menu richiede IExplorerCommand più un manifesto MSIX; IContextMenu classico è spostato sul lato «Mostra altre opzioni».
  • Per un’app che non può diventare MSIX, ottenere l’identità con uno sparse package (MSIX con posizione esterna) è la risposta realistica.
  • Se tutto ciò che volete è «aprire con questa app», un’associazione e un verb statico bastano ancora. Partire dal mezzo più semplice è anche la linea guida ufficiale.
  • Dopo registrazione, modifica o eliminazione, notificate con SHChangeNotify; alla disinstallazione eliminate il ProgID ma lasciate il valore predefinito della chiave di estensione. Windows Sandbox è comodo per la verifica.

Se un ricambio di PC Windows 11 vi ha fatto notare che «il menu è stato nascosto», confermate prima quale di (a), (b) e (c) nella tabella di decisione del capitolo 6 è. Dovreste poter stimare la scala del lavoro sul posto.

Articoli correlati

Aree di consulenza correlate

KomuraSoft LLC si occupa della progettazione e dell’implementazione di associazione file, menu contestuali ed estensioni della shell per app aziendali; del puntare al nuovo menu contestuale di Windows 11 (passaggio a IExplorerCommand, introduzione di uno sparse package); della revisione di registrazione e pulizia di un installer esistente; e dell’indagine della causa di un Esplora risorse pesante o in crash. Va bene partire dal decidere cosa fare del «menu che è stato nascosto sotto Mostra altre opzioni».

Riferimenti

  1. Microsoft Learn, File Types. Sulla struttura di una chiave di estensione che punta a un ProgID; OpenWithProgIds; la scissione della registrazione tra HKLM/HKCU\Software\Classes; la chiamata di SHChangeNotify(SHCNE_ASSOCCHANGED) dopo un cambio di associazione; e l’eliminazione del ProgID alla disinstallazione lasciando il valore predefinito della chiave di estensione.  2 3 4 5

  2. Microsoft Learn, HKEY_CLASSES_ROOT Key. Sul fatto che HKEY_CLASSES_ROOT è una vista unita di HKLM\Software\Classes e HKCU\Software\Classes; le definizioni lato utente hanno priorità su quelle lato macchina; e le regole di instradamento in scrittura.  2

  3. Microsoft Learn, Windows app defaults platform. Sul fatto che il cambio dell’app predefinita è progettato per essere fatto solo tramite l’interfaccia Impostazioni di sistema; i dati delle impostazioni utente sono offuscati e protetti in scrittura da un driver filtro (UCPD.sys); il cambio basato sul registro non è supportato; e l’uso di Criteri di gruppo / criterio MDM in un ambiente gestito.  2

  4. Microsoft Learn, Working with Shell Extensions. Sui tipi di gestore di estensione della shell; un’estensione come DLL COM in-process caricata in Esplora risorse (e nei processi che ospitano la shell), così che un crash o un blocco si propaga a Esplora risorse nel suo insieme; la registrazione con ThreadingModel=Apartment; e il considerare un’alternativa più semplice prima di un’estensione della shell.  2 3

  5. Microsoft Learn, Guidance for Implementing In-Process Extensions. Sul fatto che Microsoft non raccomanda e non supporta un’implementazione di estensione della shell in-process in codice gestito; i motivi tra cui collisioni di versione del CLR, rientranza e durata degli oggetti non deterministica; e il codice gestito accettabile per un’estensione out-of-process (un gestore di anteprima, o un avvio da shell\verb\command).  2 3

  6. Windows Developer Blog, Extending the Context Menu and Share Dialog in Windows 11. Sulla progettazione del nuovo menu contestuale di Windows 11; l’estensione tramite IExplorerCommand più identità dell’app; il collocare «Apri» e «Apri con» in cima; il raccogliere più comandi in un flyout con il nome dell’app; e le estensioni IContextMenu classiche caricate come il menu di Windows 10 sotto «Mostra altre opzioni» (Maiusc+F10).  2 3

  7. Microsoft Learn, Add a File Explorer context menu command to a packaged desktop app. Sul fatto che la registrazione nel nuovo menu contestuale di Windows 11 avviene con un’implementazione IExplorerCommand più windows.comServer più una dichiarazione di manifesto desktop4:FileExplorerContextMenus; ItemType può specificare *, Directory o Directory\Background; l’allineamento dell’architettura della DLL; il mantenere veloci i metodi di costruzione del menu; la copertura di un’app non impacchettata con uno sparse package; un riavvio di Esplora risorse a volte richiesto perché la registrazione abbia effetto; e un’associazione file che non è un’estensione di menu per uso generale.  2 3 4 5 6 7 8

  8. Microsoft Learn, Grant package identity by packaging with external location. Sull’ottenere identità di pacchetto registrando un pacchetto a posizione esterna (sparse package) senza cambiare l’installer esistente; la disponibilità da Windows 10 versione 2004 in poi; e le funzioni Windows che richiedono identità (registrazione nel menu contestuale, notifiche e simili) che diventano usabili.  2 3

  9. Microsoft Learn, Choosing a Static or Dynamic Shortcut Menu Method. Sul scegliere il metodo di verb statico più semplice che soddisfa i requisiti; IContextMenu come il più potente ma anche il più complesso e classificato verso il lato non raccomandato; e IExplorerCommand/IExplorerCommandState come il metodo raccomandato.  2

  10. Microsoft Learn, SHChangeNotify function. Su come sollevare l’evento SHCNE_ASSOCCHANGED che notifica al sistema un cambio di associazione file, e su usarlo perché la shell si accorga della modifica.  2

  11. Microsoft Learn, Application Registration. Sul fatto che la registrazione di un eseguibile tramite la sottochiave App Paths è raccomandata; il ruolo della sottochiave Applications; la registrazione di verb tramite SystemFileAssociations; e la priorità del ProgID e delle informazioni correlate quando l’app predefinita cambia. 

  12. Microsoft Learn, Creating Shortcut Menu Handlers. Su come registrare un verb statico; l’ordine in cui si decide il verb predefinito (valore predefinito → primo verb → Open → Open With); i nomi visualizzati dei verb standard forniti dal sistema operativo; i verb estesi tramite Extended; l’associazione con comandi DDE che è Deprecated; e le cautele del reindirizzamento WOW64 in un ambiente a 64 bit.  2 3

  13. Microsoft Learn, Verbs and File Associations. Sul fatto che un verb è un’azione usata anche da ShellExecuteEx; gli elementi di una stringa di comando che possono contenere uno spazio devono essere avvolti tra virgolette, e “%1” va sempre scritto tra virgolette; e la registrazione di una procedura predefinita sotto HKCR\Applications. 

  14. Microsoft Learn, IExplorerCommand interface. Sulla composizione dei metodi GetTitle, GetIcon, GetState, Invoke, EnumSubCommands e simili; i metodi chiamati sul thread UI quindi non devono comunicare con risorse di rete; e la disponibilità da Windows Vista in poi. 

  15. Microsoft Learn, Windows Sandbox. Sul poter avviare un ambiente Windows isolato e usa-e-getta in pochi secondi, tutti i cambiamenti vengono scartati quando lo chiudete, la sua idoneità per test software e verifica dell’installer, e la disponibilità su Pro/Enterprise/Education. 

Articoli recenti con gli stessi tag per approfondire argomenti vicini.

Queste pagine collocano l’argomento in un contesto più ampio di servizi e decisioni.

L’articolo è direttamente collegato ai servizi seguenti.

Domande frequenti

Domande che ricorrono nelle consulenze sull’argomento dell’articolo.

Perché la voce del menu contestuale della nostra app in Windows 11 compare solo sotto «Mostra altre opzioni»?
Perché in Windows 11 il menu contestuale di Esplora file si è diviso in due strati, vecchio e nuovo. Gli unici comandi che possono comparire nel nuovo menu sono quelle che implementano l'interfaccia IExplorerCommand e sono registrate nel manifesto di un pacchetto MSIX (= hanno identità di pacchetto). Le estensioni della shell classiche basate su IContextMenu sono state spostate nel vecchio menu che si apre con «Mostra altre opzioni» (Maiusc+F10). L'estensione in sé non è rotta, quindi per ora continua a funzionare, ma se la si vuole nel nuovo menu serve una migrazione a IExplorerCommand e il packaging come MSIX oppure l'identità con uno sparse package.
L'installer può impostare la nostra app come app predefinita per un file (quella che si apre con il doppio clic)?
No. La scelta dell'app predefinita è progettata perché la faccia l'utente, e Windows non supporta il cambio dell'app predefinita da nessun altro posto se non l'interfaccia Impostazioni di sistema. Le informazioni UserChoice che conservano la scelta di ogni utente sono offuscate, e un driver filtro (UCPD.sys) protegge anche in scrittura dalle app. Ciò che un installer può fare è registrare un ProgID e i verb, aggiungersi a OpenWithProgIds per comparire come candidato in «Apri con» e indirizzare l'utente alla pagina App predefinite. L'implementazione corretta non è rubare il predefinito, ma prepararsi a essere scelti.
Posso scrivere un'estensione della shell in codice gestito come C#?
Microsoft ha detto chiaramente che scrivere un'estensione della shell in-process (un gestore di menu contestuale, un gestore di icone e simili) in codice gestito non è raccomandato e non è supportato. L'estensione viene caricata in Esplora risorse e nel processo di qualsiasi app che apre una finestra di dialogo file comune, quindi collisioni di versione del CLR, rientranza e durata degli oggetti non deterministica rendono instabile l'app ospite. La regola è l'implementazione in C++ nativo. Un EXE normale avviato dal command di un verb, o un'estensione out-of-process come un gestore di anteprima che gira in un processo separato, va bene in codice gestito.
Che cos'è uno sparse package (MSIX con posizione esterna)?
Un piccolo pacchetto MSIX che non contiene file dell'app, solo un manifesto (informazioni di identità). Per un'app installata in modo ordinario con un installer esistente (MSI, Inno Setup e simili), lo si registra con Add-AppxPackage -ExternalLocation che punta alla cartella di installazione, e l'app acquisisce identità di pacchetto e può usare funzioni che la richiedono, come la registrazione nel nuovo menu contestuale di Windows 11 e le notifiche toast. È disponibile da Windows 10 versione 2004 in poi, e il pacchetto necessita di una firma del codice attendibile sulla macchina di destinazione. È l'opzione realistica quando si vuole il supporto del nuovo menu senza spostare l'intera distribuzione su MSIX.
Cosa fare quando una voce del menu contestuale compare due volte, o non scompare?
Per prima cosa isolate la causa controllando su quale menu compare: il nuovo o il vecchio (Mostra altre opzioni). La doppia visualizzazione tipica è che coesistono una registrazione classica nel registro e una registrazione nel manifesto MSIX, o che una registrazione ProgID o CLSID dell'estensione è rimasta alla disinstallazione. Dopo un cambio di associazione sospettate anche un SHChangeNotify(SHCNE_ASSOCCHANGED) dimenticato; subito dopo la registrazione del pacchetto, un riavvio di Esplora risorse dimenticato. Se ancora non si risolve, disabilitate temporaneamente le estensioni non Microsoft in ShellExView e identificate la DLL colpevole con una ricerca binaria.

Profilo dell’autore

Pagina di presentazione dell’autore dell’articolo.

Go Komura

Rappresentante di KomuraSoft LLC

Specializzato nello sviluppo di software Windows, nella consulenza tecnica e nell’analisi dei malfunzionamenti, soprattutto nei progetti con sistemi esistenti e guasti difficili da riprodurre.

Torna al blog