El estado actual de la integración con el shell de Windows — menú contextual, asociación de archivos y los cambios de Windows 11

· Actualizado el: · · Windows, Extensiones de shell, Menú contextual, Asociación de archivos, COM, Windows 11, Explorador, MSIX, Desarrollo en Windows

Historial de revisiones (primera versión, publicada el 20 Aug 2026)
Primera publicación
Citar este artículo(DOI (archivo registrado): 10.5281/zenodo.22176254)

Los DOI siguientes remiten a versiones ya archivadas y pueden diferir del texto actual. Para citar el texto actual, utilice la URL de esta página.

Go Komura (2026). El estado actual de la integración con el shell de Windows — menú contextual, asociación de archivos y los cambios de Windows 11. KomuraSoft LLC. https://comcomponent.com/es/blog/windows-shell-integration-context-menu-file-association/

DOI (archivo registrado)
10.5281/zenodo.22176254
DOI (última versión registrada)
10.5281/zenodo.22176255

«Tras pasar a Windows 11, no encontramos el menú contextual de nuestra aplicación». Al comprobarlo, el elemento no ha desaparecido: si se abre «Mostrar más opciones» al final del menú, aparece. Lo que ocurre en esta consulta no es un fallo, sino un cambio de diseño del menú en Windows 11. En el terreno conduce a consultas del tipo «hace falta un clic más» o «no encuentro el elemento».

Sin embargo, «abrir un archivo con esta aplicación» y «poner un comando propio en el menú contextual nuevo» son respuestas distintas. Si se empieza a escribir una DLL de extensión de shell sin separarlas, se complica un requisito que se resolvía solo con el registro de la asociación.

Este artículo es una introducción para responsables de sistemas de pequeñas y medianas empresas y para desarrolladores de Windows que custodian aplicaciones de negocio. Conecta la base de la asociación de archivos, la diferencia entre el menú nuevo y el antiguo, la elección del método de implementación, el registro y la eliminación en el instalador, y el aislamiento de fallos.

1. Primero la conclusión

La base de la asociación y de los verb no ha cambiado; en Windows 11, la forma de mostrar el menú se dividió en nueva y antigua. Primero decida qué quiere lograr y elija solo los mecanismos que ese objetivo necesita.

Si solo es «abrir», empiece por la asociación y el verb estático

La base de la asociación de archivos es la estructura de tres niveles del Registro «clave de extensión → ProgID → verb». La clave de extensión apunta a un ProgID, y shell\<verb>\command bajo el ProgID tiene la línea de comandos que se arranca. Si solo quiere «abrir con esta aplicación», sigue bastando este registro y el verb estático, y no hace falta una DLL de extensión de shell. Microsoft también indica que se empiece por el verb estático más simple que cubra el requisito.12

El destino del registro es HKLM si es para todos los usuarios, y HKCU si es por usuario. HKCR es una vista compuesta que superpone Classes de ambos, así que el destino de escritura se indica como HKLM o HKCU, y HKCR se piensa para comprobar.3

Además, el registro como candidato y la elección como aplicación predeterminada son cosas distintas. La aplicación predeterminada que abre con doble clic la elige el usuario, y el SO protege esa elección. El trabajo del lado de la aplicación no es que el instalador arrebate el valor predeterminado, sino registrarse correctamente como candidato.4

Si va a poner un comando propio en el menú nuevo, hacen falta IExplorerCommand e identidad de paquete

En Windows 11, una extensión IContextMenu tradicional se relega al menú antiguo que se abre con «Mostrar más opciones» (Shift+F10). Para cargar un comando propio en el menú nuevo hacen falta una implementación de IExplorerCommand e identidad de paquete.56

La ruta oficial es registrar en el manifiesto MSIX (desktop4:FileExplorerContextMenus) una DLL nativa que implementa IExplorerCommand. Si no se puede pasar la aplicación existente por completo a MSIX, se puede dar solo la identidad con un sparse package (MSIX con ubicación externa).67

Piense también en la seguridad de la DLL y en la limpieza al desinstalar

Una extensión de shell tradicional es una DLL COM que se carga en el proceso del Explorador y similares. Un bloqueo o un retraso de la extensión se propagan a todo el host. Un host de 64 bits necesita una DLL de 64 bits, y implementar una extensión en proceso en código administrado no tiene soporte.89

Tras registrar, cambiar o eliminar una asociación, notifique con SHChangeNotify(SHCNE_ASSOCCHANGED). En la desinstalación, elimine el ProgID propio y similares, y deje el valor predeterminado de la clave de extensión: esa es la guía oficial. La integración con el shell no es solo mostrar el menú: incluye que el cambio se aplique y la limpieza posterior.110

Cómo leerlo según el objetivo

Lo que quiere saber o el síntoma Dónde leerlo
Qué método de implementación elegir Tabla de decisión del capítulo 6. Separe si es solo asociación o si añade un comando propio al menú nuevo
Quiero responder al doble clic o a «Abrir con» Asociación del capítulo 2 y verb estático del capítulo 3
Lo registré y no queda como aplicación predeterminada UserChoice de la sección 2.4. Separe el registro como candidato de la elección del usuario
En Windows 11 el menú se ha escondido un nivel más adentro Menús nuevo y antiguo del capítulo 5. El método, sección 5.2; si no se puede pasar a MSIX, sección 5.3
Qué registrar y quitar en el instalador Capítulo 7. En particular el registro por usuario de la sección 7.3 y la limpieza de la sección 7.4
El menú no aparece, aparece duplicado o el Explorador va pesado Aislamiento del capítulo 8. Las restricciones de la DLL, capítulo 4

Si va a aprender el mecanismo, lea en orden desde el capítulo 2; si va a decidir la política de una aplicación existente, desde el capítulo 6.

En el diagrama, una línea continua marca una relación que siempre se cumple y una línea discontinua una relación condicional (las condiciones están en la explicación de cada relación en la página de detalle). La lista completa de relaciones (16 en total, con evidencia y grado de certeza) y las definiciones de los conceptos principales están reunidas en la página de detalle del mapa de conocimiento (en japonés). Datos: JSON-LD / Turtle

2. El mecanismo de la asociación de archivos — la estructura de tres niveles clave de extensión → ProgID → verb

En este capítulo se organiza en el orden registro del lado del archivo → destino de escritura → registro del lado de la aplicación → elección del usuario. La base —la extensión apunta a un ProgID, el verb tiene la línea de comandos y una extensión más elaborada funciona como DLL COM en proceso— no ha cambiado en más de 20 años.

2.1. Leer la estructura de tres niveles en un solo ejemplo

Primero, vea la forma básica de la asociación en un ejemplo. La clave de extensión apunta a un ProgID, y el verb de su interior tiene el comando que se arranca.1 La prioridad cuando el usuario ha elegido una aplicación predeterminada se explica en la sección 2.4.

HKEY_CLASSES_ROOT
   .kmrpt                                  ← (1) clave de extensión
      (Default) = KomuraSoft.Report.1      ←     solo un puntero al ProgID
      OpenWithProgids
         KomuraSoft.Report.1               ←     candidato de «Abrir con»
   KomuraSoft.Report.1                     ← (2) ProgID (entidad de la asociación)
      (Default) = Documento de informe KomuraSoft
      DefaultIcon
         (Default) = "C:\Program Files\KomuraSoft\Report.exe",0
      shell                                ← (3) lista de verb (verbos)
         open
            command
               (Default) = "C:\Program Files\KomuraSoft\Report.exe" "%1"
  • (1) La clave de extensión (.kmrpt) solo apunta, en el valor predeterminado, al nombre del ProgID. Escribir el comando aquí es un error.
  • (2) El ProgID (KomuraSoft.Report.1) es la entidad de la asociación y tiene el nombre mostrado, el icono y la lista de verb.
  • (3) El verb es un verbo como «abrir» o «imprimir», y el valor predeterminado de shell\open\command es la línea de comandos que se arranca de verdad.

Gracias a esta separación se pueden orientar varias extensiones (.kmrpt y .kmrpt-file, etc.) al mismo ProgID, o sustituir el ProgID al subir de versión la aplicación.

Estructura de tres niveles de la asociación de archivosLa clave de extensión es un puntero que en el valor predeterminado apunta al ProgID; el ProgID es la entidad que tiene el nombre mostrado, el icono y la lista de verb; el valor predeterminado de command bajo el verb es la línea de comandos que se arranca de verdaden el valor predeterminado apunta al ProgIDClave de extensión .kmrptProgID KomuraSoft.Report.1verb (open bajo shell, etc.)Valor predeterminado de commandSe arranca Report.exeTambién tiene el nombre mostrado y DefaultIcon

Figura 1: La clave de extensión es el puntero, el ProgID es la entidad y command del verb es la línea de comandos que se arranca de verdad.

2.2. HKCR es una «vista compuesta» — el significado cambia según dónde se escriba

El ejemplo de arriba se mostró en HKEY_CLASSES_ROOT (HKCR), pero HKCR no es un lugar de almacenamiento físico, sino una vista compuesta que superpone HKLM\Software\Classes y HKCU\Software\Classes. Si la misma clave está en ambos, gana el lado HKCU.3

HKCR es una vista compuestaLo que se superpone de Classes de HKLM y de HKCU es HKCR; si la misma clave está en ambos, gana HKCU; la escritura del registro indica HKLM o HKCU y HKCR se reserva para lecturaHKLM\Software\Classes (todos los usuarios)HKCR (vista compuesta)HKCU\Software\Classes (por usuario)Si la misma clave está en ambos, gana HKCUSe reserva para lectura (comprobación)

Figura 2: HKCR es la apariencia de superponer Classes de HKLM y HKCU; el destino de escritura se indica siempre como uno de los dos.

Destino de escritura Significado Privilegios necesarios
HKLM\Software\Classes Registro común a todos los usuarios Privilegios de administrador
HKCU\Software\Classes Registro solo de ese usuario No hacen falta
Escribir de forma directa en HKCR Se reparte según el lugar de la clave existente Según el caso

En la práctica, lo seguro es escribir el registro indicando siempre HKLM o HKCU, y reservar HKCR para lectura (comprobación).

No confunda los datos de asociación con el bitness del registro COM

En la redirección del Registro de WOW64, el trato de los datos de asociación y del registro COM es distinto. Los datos de asociación bajo HKLM\Software\Classes —clave de extensión, ProgID, etc.— se comparten entre las vistas de 32 y 64 bits del Registro a partir de Windows 7, y aunque los escriba un instalador de 32 bits no se escapan al lado Wow6432Node.

En cambio, algunas subclaves del registro COM, como Classes\CLSID, sí son objeto de redirección, y en el registro de una extensión de shell (COM en proceso) que se verá más adelante influye escribir por separado 32 y 64 bits. Los detalles están en «Redirección y virtualización de 32/64 bits en el registro de Windows».

2.3. Registro del lado de la aplicación — App Paths, Applications, RegisteredApplications

Hay también tres tipos de registro del lado de la aplicación, que van emparejados con el lado del archivo (extensión y ProgID).11

  • App Paths (HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths): registro para poder arrancar desde ShellExecuteEx solo con el nombre del archivo ejecutable. Evita ensuciar la variable de entorno PATH, y Microsoft lo recomienda.
  • Applications (HKCR\Applications\<aplicación.exe>): define la forma predeterminada de abrir cuando se le pasa un archivo cualquiera en «Abrir con», y el nombre mostrado de la aplicación (FriendlyAppName).
  • RegisteredApplications + Capabilities: declara las extensiones y tipos MIME que la aplicación maneja, y es el registro para aparecer como candidato en la pantalla de configuración de aplicaciones predeterminadas de Windows.

La mayoría de las consultas de «nuestra aplicación no sale en la lista de aplicaciones predeterminadas» son casos en los que se registró el ProgID pero se omitió este registro de Capabilities.

Tres tipos de registro del lado de la aplicaciónEl registro del lado de la aplicación tiene tres tipos —App Paths, Applications y RegisteredApplications— y cada uno asume el arranque solo con el nombre del ejecutable, la forma predeterminada de Abrir con, y aparecer en la pantalla de aplicaciones predeterminadasRegistro del lado de la aplicaciónApp PathsApplicationsRegisteredApplicationsArrancar solo con el nombre de archivoForma predeterminada de Abrir conAparecer en la pantalla de aplicaciones predeterminadasLa condición es declararlo en Capabilities

Figura 3: El registro del lado de la aplicación es de tres tipos, y para aparecer como candidato en la pantalla de aplicaciones predeterminadas hace falta el registro de Capabilities.

2.4. La aplicación predeterminada es del usuario — la protección de UserChoice

Aunque se escriba un ProgID en el valor predeterminado de la clave de extensión, eso no basta para convertirse en la aplicación predeterminada. El resultado de que el usuario elija de forma explícita en «Abrir con» y similares se conserva en HKCU\...\Explorer\FileExts\<extensión>\UserChoice, y en la resolución de la asociación este tiene prioridad.

No diseñe reescribir UserChoice de forma directa

Windows no admite el cambio programático de la aplicación predeterminada. La configuración de la aplicación predeterminada está diseñada para que el usuario la haga a través de la interfaz de configuración del sistema; los datos de UserChoice están ofuscados y un controlador de filtro (UCPD.sys) bloquea las escrituras desde las aplicaciones. En un entorno administrado, el medio oficial es Directiva de grupo o una directiva MDM.4

Que en el pasado se usaran herramientas como SetUserFTA que «imitan el hash y reescriben» es el reverso de esta protección.

El instalador hace «la preparación para ser elegido»

Lo que se incorpora al instalador de la aplicación propia son estas tres cosas.

  1. Registrar correctamente el ProgID y el verb.
  2. Añadirse a OpenWithProgIds.
  3. Si hace falta, inducir al usuario a la pantalla de configuración de aplicaciones predeterminadas.

No se arrebata el valor predeterminado: se deja el estado en el que el usuario puede elegir.

Resolución de la aplicación predeterminada y protección de UserChoiceEl resultado que el usuario elige de forma explícita se conserva en UserChoice y tiene prioridad en la resolución de la asociación; UCPD.sys corta la reescritura desde la aplicación, de modo que lo que el instalador puede hacer llega hasta el registro como candidato y la inducción a la pantalla de configuraciónprioridadUCPD.sys lo cortaUserChoice (elección del usuario)Resolución de la asociaciónValor predeterminado de la clave de extensiónReescritura desde la aplicaciónTrabajo del instaladorRegistro de ProgID y verbAñadirse a OpenWithProgIdsInducción a la pantalla de configuración

Figura 4: En la resolución de la asociación tiene prioridad la elección del usuario (UserChoice), y el SO protege contra la reescritura desde la aplicación.

3. Verbs distintos de «abrir» — print, edit, runas y verb personalizado

3.1. Verbs estándar y verbs personalizados

El verb no es solo open. Entre los verbs estándar cuyo significado conoce el SO están, además de open, edit, print, play, preview, etc., y a un verb estándar se le asigna de forma automática un nombre mostrado según la configuración regional del SO. El verb predeterminado que se usa al hacer doble clic se decide en el orden valor predeterminado de la clave shell → primer verb en el Registro → open → openwith.12

Orden de decisión del verb predeterminadoEl verb predeterminado que se usa al hacer doble clic se decide como el primero que se encuentra, en el orden valor predeterminado de la clave shell, primer verb en el Registro, open, openwithsi no haysi no haysi no hayValor predeterminado de la clave shellPrimer verb en el Registroopenopenwith

Figura 5: El verb predeterminado al hacer doble clic es el primero que se encuentra en este orden.

Si quiere añadir un verbo propio, registre un verb personalizado.

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 personalizado
         (Default) = Verificar el informe(&V)   ← nombre mostrado en el menú
         command
            (Default) = "C:\Program Files\KomuraSoft\Report.exe" /verify "%1"

3.2. Distinguir la elevación, la visualización con Mayús y el DDE antiguo

En un verb también hay especificaciones como las siguientes.

  • Si se registra un verb runas, se define un arranque elevado equivalente a «Ejecutar como administrador», y también se usa en un arranque que especifica runas desde las API de la familia ShellExecute.
  • Si se coloca un valor vacío Extended en la clave del verb, se convierte en un verb extendido que solo se muestra al hacer clic derecho manteniendo Mayús. Es útil para ocultar una operación peligrosa que se usa rara vez.12
  • En la asociación de una aplicación antigua a veces queda una configuración que envía el documento a un proceso existente con DDE (clave ddeexec), pero el arranque de un verb por DDE es ya un legado no recomendado (Deprecated). No hay motivo para escribirlo de nuevo.12

3.3. Entrecomillar la ruta del EXE y la ruta del archivo seleccionado

Donde más accidentes hay es en las comillas de la línea de comandos. Si un elemento de la cadena de comando puede incluir un espacio, hay que entrecomillarlo siempre. Una ruta de EXE como C:\Program Files\... por supuesto, y %1 (la ruta del archivo seleccionado) debe escribirse siempre como "%1". No se puede garantizar que la ruta de archivo del usuario no incluya un espacio. Un My Program.exe sin comillas se interpreta como «arrancar My con el argumento Program.exe».13

Accidente de las comillas de la línea de comandosUn comando sin comillas se parte en la posición del espacio y se malinterpreta como arrancar My con el argumento Program.exe, de modo que la ruta del EXE que puede incluir un espacio y %1, que representa la ruta del archivo seleccionado, se entrecomillan siemprese parte por el espaciocommand sin comillasMalinterpretación como arranque de otro EXEcommand con comillasArranca como se pretendíaEntrecomillar la ruta del EXEEntrecomillar también %1 siempre

Figura 6: Un comando sin comillas se parte mal por el espacio, así que la ruta del EXE y %1 se entrecomillan siempre.

3.4. Antes de escribir una DLL, compruebe si basta un verb estático

El mecanismo de solo Registro de hasta aquí (verb estático) se puede lograr sin escribir ninguna DLL, y no hay riesgo de inestabilizar el Explorador. El propio Microsoft dice de forma reiterada: «antes de escribir una extensión de shell, estudie si no basta el verb estático más simple que cubra el requisito».2

4. Extensión de shell tradicional — una DLL que se ejecuta dentro del Explorador

Lo que hay que retener en este capítulo es que una DLL de extensión tradicional se ejecuta dentro del proceso del Explorador y similares. Si se entiende el lugar de ejecución, se conectan las restricciones de estabilidad, bitness y lenguaje de implementación.

4.1. Tipos de extensión de shell

Para requisitos que el verb estático no cubre —«cambiar el menú de forma dinámica según la selección», «sustituir el icono o la pantalla de propiedades»— se usa un controlador de extensión de shell. Los tipos representativos son los siguientes.8

Controlador Interfaz principal Lo que puede hacer
Controlador de menú contextual IContextMenu + IShellExtInit Añadir y controlar elementos de menú de forma dinámica
Controlador de iconos / superposición de iconos IExtractIcon / IShellIconOverlayIdentifier Icono por archivo y superposición
Controlador de hoja de propiedades IShellPropSheetExt Añadir una pestaña a la pantalla de propiedades
Miniatura / infotip IThumbnailProvider / IQueryInfo Vista reducida y descripción al pasar el puntero
Controlador de arrastrar y colocar / de gancho de copia IDropTarget / ICopyHook Intervención al soltar o al copiar y mover

Todos se implementan como clase COM y se registra el CLSID en el Registro. La idea de COM en sí está en «Qué son COM, ActiveX y OCX».

4.2. El significado de ser un servidor COM en proceso

La esencia de una extensión de shell tradicional es que es un servidor COM en proceso (DLL) que se carga en el proceso del Explorador (o de cualquier aplicación que abra un cuadro de diálogo de archivos común). De ahí se derivan todas las precauciones.8

  • Si la extensión se bloquea, el Explorador se bloquea de arrastre. Si se cuelga, el clic derecho se queda congelado varios segundos. El daño no se limita al Explorador: alcanza a todas las aplicaciones que muestran un cuadro de diálogo para abrir un archivo.
  • La construcción del menú se hace en el hilo de la interfaz, así que no hay que hacer en la visualización del menú un procesamiento lento como un acceso de red o E/S de archivo.
  • El modelo de subprocesos se registra en principio como Apartment.
Estructura de arrastre de una extensión en procesoLa DLL de extensión de shell se carga no solo en el Explorador, sino también en el proceso de cualquier aplicación que abra un cuadro de diálogo de archivos, de modo que un bloqueo o un cuelgue de la extensión se propagan a todo el proceso anfitriónse carga en el procesose carga en el procesoDLL de extensión de shellExploradorCualquier aplicación que abra el cuadro de diálogoSe propaga el bloqueo o el cuelgueNo hacer un procesamiento lento al mostrar

Figura 7: La DLL de extensión se ejecuta dentro del proceso anfitrión, de modo que un bloqueo o un cuelgue se propagan a todo el anfitrión.

Al investigar una consulta de «al abrir una carpeta concreta el Explorador se queda congelado» o «el clic derecho tarda 5 segundos», no es raro que la causa no sea la aplicación propia, sino una extensión de shell de un tercero. El método de aislamiento se trata en el capítulo 8.

4.3. Coincidencia de bitness — en un entorno de 64 bits hace falta una DLL de 64 bits

Una DLL en proceso debe coincidir en bitness con el proceso que la carga. El Explorador de Windows de 64 bits es un proceso de 64 bits, así que una DLL de extensión de shell compilada solo en 32 bits no se carga en absoluto y no aparece en el menú. Tampoco sale un error, de modo que es la causa clásica de «lo registré y no aparece».

No hace falta pasar también el cuerpo de la aplicación a 64 bits

La combinación de un cuerpo de aplicación de 32 bits y una DLL de extensión de shell de 64 bits es una configuración legítima, pero hay que tener en cuenta que el registro COM se divide por bitness (Wow6432Node). Además, lo que arranca el command de un verb es un EXE de otro proceso, así que no recibe esta restricción (un EXE de 32 bits no tiene problema).

Coincidencia de bitness de la DLL de extensión de shellLo único que puede cargar el Explorador de 64 bits es una DLL de extensión de shell de 64 bits; una DLL solo de 32 bits no aparece en el menú sin error; el EXE que arranca el command de un verb es otro proceso y no recibe la restricciónpuede cargarno puede cargarotro procesoExplorador de 64 bitsDLL de extensión de shell de 64 bitsDLL solo de 32 bitsNo aparece en el menú, sin errorEXE que arranca el verbUn 32 bits no tiene problema

Figura 8: Lo que carga el Explorador de 64 bits es solo una DLL de 64 bits; el EXE que arranca el verb no recibe esta restricción.

4.4. Por qué no hay que escribirla en código administrado

Recibimos a menudo la pregunta de «¿se puede escribir una extensión de shell en C#?», pero Microsoft declara de forma explícita que escribir una extensión de shell en proceso en código administrado (.NET) no es recomendable y queda fuera de soporte.9

La razón está en la naturaleza de que la extensión se carga en un proceso cualquiera. Los factores que desestabilizan la aplicación anfitriona son, principalmente, estos tres.

  • Conflicto de versión del CLR. El problema se da sobre todo por debajo de .NET Framework 4.
  • Reentrada. Hay un problema de que, al esperar un bloqueo, el CLR reentra en el bucle de mensajes.
  • Vida de los objetos. La falta de determinismo de la vida por el recolector de elementos no utilizados choca con el contrato de recuento de referencias de COM.

Hay elementos mitigados a partir de .NET Framework 4 y en .NET moderno, pero la postura oficial no ha cambiado.

La pauta práctica es simple. Una extensión en proceso se escribe en C++ nativo. Si se quiere usar código administrado, se convierte en un EXE normal que arranca el command de un verb, o en una extensión fuera de proceso que se ejecuta en otro proceso (controlador de vista previa, etc.).9

Decisión de si se puede usar código administradoUna extensión en proceso que se ejecuta dentro del proceso del Explorador se escribe en principio en C++ nativo; si se quiere usar código administrado, se convierte en un EXE normal que arranca el command de un verb o en una extensión fuera de proceso que se ejecuta en otro procesosíno¿Extensión que se ejecuta dentro del proceso?Escribirla en C++ nativoTambién vale código administradoEl anfitrión se desestabiliza por conflicto de CLR o reentradaEXE normal que arranca el verbExtensión en otro proceso, como una vista previa

Figura 9: Una extensión en proceso se escribe en principio en C++ nativo; el código administrado se limita a una configuración que se ejecuta en otro proceso.

5. El nuevo menú contextual de Windows 11 — la duplicación del menú

Aquí se explica en el orden por qué se pasó al menú antiguo → registro en el menú nuevo → cómo mantener el instalador existente. La diferencia entre una asociación que solo es «abrir con esta aplicación» y la adición de un comando propio se confirma en la sección 5.4.

5.1. Qué ocurrió

Windows 11 renovó el menú contextual del Explorador. Cortar, copiar, etc. pasan a una fila de iconos en la parte superior, «Abrir» y «Abrir con» se colocan juntos arriba, y los comandos que añade una aplicación se agrupan bajo los comandos estándar del shell. Si una aplicación añade varios comandos, se reúnen en un flyout (submenú) con el nombre de la aplicación.5

Y el punto clave es este. Una extensión de shell tradicional basada en IContextMenu no se ha eliminado: se ha relegado al menú antiguo que se abre con «Mostrar más opciones» (Shift+F10), que carga tal cual el menú de Windows 10.5 La realidad del «el menú se ha escondido» de la consulta del principio es esta duplicación.

Menú contextual duplicado en Windows 11Lo que se abre primero al hacer clic derecho es el menú nuevo, y lo que se carga ahí son solo los comandos registrados con IExplorerCommand e identidad de paquete; una extensión IContextMenu tradicional se relega al menú antiguo que se abre con Mostrar más opcionesMostrar más opciones Shift+F10Clic derecho en un archivoMenú nuevo (Windows 11)Comando con IExplorerCommand e identidadMenú antiguo (el menú de Windows 10)Extensión IContextMenu tradicionalVarios comandos se reúnen en un flyout

Figura 10: En el menú nuevo solo se cargan los comandos con IExplorerCommand e identidad; una extensión tradicional se relega al menú antiguo.

5.2. La ruta oficial para cargarlo en el menú nuevo — IExplorerCommand + registro en el manifiesto

La ruta oficial para poner un comando propio en el menú nuevo es una DLL nativa que implementa IExplorerCommand y el registro en el manifiesto MSIX.6

En el manifiesto se escriben dos tipos de declaración

El ejemplo siguiente declara, en la primera mitad, el servidor COM (CLSID y DLL de implementación) y, en la segunda, la extensión de menú contextual (destino y comando). Lo que une ambos es el mismo CLSID.

<!-- Manifiesto del paquete (extracto) -->
<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>

En Type de ItemType se puede especificar, además de una extensión concreta, * (todos los archivos), Directory (carpeta) y Directory\Background (fondo de una carpeta). La DLL se hace coincidir con la arquitectura del Explorador (64 bits/ARM64).6

Los métodos de construcción del menú deben devolver rápido

IExplorerCommand es una interfaz que existe desde la era de Windows 7, e implementa el título (GetTitle), el icono (GetIcon), el estado habilitado/deshabilitado/oculto (GetState) y la ejecución (Invoke). Los métodos se llaman desde el hilo de la interfaz, así que está prohibido el acceso a un recurso de red, y los métodos de construcción del menú deben devolver rápido. El procesamiento pesado se hace después de Invoke.146

Estructura del manifiesto del registro en el menú nuevoLa declaración de servidor COM del manifiesto MSIX hace corresponder CLSID y DLL, y la declaración de extensión de menú contextual une destino e implementación con ItemType y Verb, de modo que el comando propio se muestra en el menú nuevohace corresponder CLSID y DLLespecifica con ItemType y VerbManifiesto MSIXDeclaración de servidor COMDeclaración de extensión de menúDLL que implementa IExplorerCommandEl comando se muestra en el menú nuevoEl destino es una extensión, todos los archivos, etc.

Figura 11: Las dos declaraciones del manifiesto unen la DLL de implementación y el destino, y el comando se carga en el menú nuevo.

5.3. La opción de una aplicación no empaquetada — obtener solo la identidad con un sparse package

La vía de escape cuando «nuestra aplicación no se puede distribuir si no es MSI; pasar a MSIX es imposible» es el sparse package (MSIX con ubicación externa). Se firma un MSIX pequeño, solo manifiesto, que no incluye el cuerpo de la aplicación, y se registra al final del instalador existente. Así la aplicación obtiene identidad de paquete y se hace posible el registro en el manifiesto de arriba (es decir, mostrarse en el menú nuevo).

Se puede usar desde Windows 10 versión 2004, y hace falta la firma del paquete con un certificado de confianza en el equipo de destino.7 El orden de registro y anulación, y la precaución de que el registro es por usuario, se tratan en la sección 7.3.

Flujo para obtener identidad con un sparse packageTras colocar el cuerpo de la aplicación con el instalador existente, si se registra un sparse package de solo manifiesto con ubicación externa, la aplicación obtiene identidad de paquete y se hace posible el registro en el manifiesto para el menú nuevoInstalador existenteColocar el cuerpo de la aplicaciónsparse packageSolo manifiesto, sin cuerpoRegistrar con ubicación externaObtiene identidad de paqueteSe hace posible el registro en el menú nuevoHace falta una firma de confianza

Figura 12: Si se registra un sparse package que no incluye el cuerpo, con ubicación externa, la aplicación obtiene identidad de paquete.

La mayor ventaja es no tener que sustituir el instalador, y es la respuesta realista para una aplicación que ya tiene un activo de instalador MSI/EXE. Para la comparación con una migración completa a MSIX, véase también «Cómo elegir el método de distribución de aplicaciones de Windows».

5.4. Cómo se ve el verb de la asociación en el menú nuevo

Un punto fácil de malinterpretar: la asociación de los capítulos 2 y 3 (ProgID y verb) sigue viva también en el menú nuevo. El verb predeterminado del doble clic, «Abrir» y los candidatos de «Abrir con» se resuelven a partir de la asociación y se muestran en la parte superior del menú nuevo. Es decir, si solo quiere «poder abrir con esta aplicación», en Windows 11 no hace falta ninguna respuesta adicional.

En cambio, la asociación no es una extensión de menú de uso general, de modo que si quiere poner un comando personalizado cualquiera en el primer nivel del menú nuevo, hacen falta IExplorerCommand e identidad: esa es la división de papeles.6

División de papeles entre la asociación y el menú nuevoLa asociación de ProgID y verb se usa también en el menú nuevo para resolver el verb predeterminado del doble clic, Abrir y Abrir con, y se muestra arriba; para poner un comando personalizado cualquiera en el primer nivel del menú nuevo hacen falta IExplorerCommand e identidadAsociación (ProgID y verb)Resolución del verb predeterminado y de AbrirSe muestra en la parte superior del menú nuevoEn Windows 11 no hace falta respuesta adicionalComando personalizado cualquieraIExplorerCommand e identidadSe muestra en el primer nivel del menú nuevo

Figura 13: La asociación sigue resolviendo lo de «abrir» también en el menú nuevo; solo un comando personalizado exige IExplorerCommand e identidad.

6. Tabla de decisión práctica — cuál de las tres opciones tomar

Confirme primero si basta (a) y, si hace falta mostrar un comando propio en el menú nuevo, elija (b). Mantener de momento una extensión tradicional existente es (c).

Lo que quiere lograr Medio recomendado Cómo se ve en Windows 11 Trabajo y coste necesarios
(a) Arrancar la aplicación propia con doble clic o «Abrir» Asociación + verb estático (solo registro en el Registro) Visualización integrada en «Abrir» y «Abrir con» del menú nuevo Solo el registro del Registro del instalador. No hace falta DLL ni un requisito adicional de firma
(b) Poner en el menú nuevo un comando propio sobre el archivo o la carpeta seleccionados Implementación de IExplorerCommand + registro en el manifiesto MSIX. Una aplicación no empaquetada obtiene identidad con un sparse package Primer nivel del menú nuevo (varios comandos se reúnen en un flyout con el nombre de la aplicación) DLL nativa en C++ + identidad de paquete + firma de código
(c) Seguir usando una extensión IContextMenu tradicional existente Mantenerla de momento tal cual (no se elige para un desarrollo nuevo) Solo el lado del menú antiguo de «Mostrar más opciones» (Shift+F10) Mantener la compilación de 64 bits y el registro COM. En el futuro, planificar la migración a (b)

Decisión 1: elegir el método más simple que cubra el requisito

Lo primero es no sacar (b) ni (c) para un requisito que se resuelve con (a). En el momento en que se escribe una extensión de shell, se asume la responsabilidad sobre la estabilidad del Explorador.

Decisión 2: separar el mantenimiento del menú antiguo de la mejora de la usabilidad

(c) es solo «no está roto»; como experiencia de usuario, se queda en una posición un nivel inferior. Cuanto más frecuente es el comando en la operación cotidiana, mayor es el retorno de la inversión de migrar a (b).

Cómo elegir entre las tres opcionesSi solo se quiere arrancar con doble clic o Abrir, bastan la asociación y el verb estático; si se quiere un comando propio en el menú nuevo, IExplorerCommand y el registro en el manifiesto MSIX; si no se puede pasar a MSIX, se da identidad con un sparse package; una extensión IContextMenu tradicional existente se mantiene de momento en el menú antiguosínosísínono¿Basta con abrir?Asociación + verb estático¿Comando propio en el menú nuevo?¿Se puede pasar a MSIX?IExplorerCommand + MSIXIdentidad con sparse packageMantener de momento la tradicionalSolo se muestra en el menú antiguoSin DLL y con poco riesgo

Figura 14: Según el requisito, se elige entre verb estático, IExplorerCommand e identidad, o mantener la tradicional.

7. Práctica del despliegue y el registro — instalador, sparse package y limpieza

Cuando el método de implementación está decidido, se incorporan al instalador el destino de registro, la notificación de cambio, el registro y la anulación del paquete, y la limpieza al desinstalar.

7.1. ¿HKLM o HKCU?

El destino de registro se alinea con la forma del instalador. Si es para todos los usuarios (colocación en Program Files, privilegios de administrador), HKLM\Software\Classes; si es una instalación por usuario (sin elevación), HKCU\Software\Classes. Mezclarlos genera consultas del tipo «A puede abrir y B no».

En una extensión de shell que conlleva registro de CLSID, la opción de Reg-Free COM, que hace innecesario el propio registro en el Registro, es válida para el uso de COM dentro de la aplicación, pero no se puede aplicar a una extensión de shell que carga el Explorador, así que hace falta el registro de la vía directa («¿Qué es Reg-Free COM?»).

7.2. Tras un cambio, notificar — SHChangeNotify

Tras registrar, cambiar o eliminar una asociación, se notifica el evento SHCNE_ASSOCCHANGED con SHChangeNotify. Si se omite, a veces el Explorador no reconoce el cambio hasta un reinicio.110

// Llamarlo una vez, por ejemplo en una acción personalizada del instalador, tras cambiar la asociación
SHChangeNotify(SHCNE_ASSOCCHANGED, SHCNF_IDLIST, nullptr, nullptr);

7.3. Registro y anulación de un sparse package

El registro y la anulación de un sparse package son trabajo del instalador. El registro se hace después de colocar los archivos; la anulación, antes de eliminarlos.7

# Al instalar: tras colocar los archivos, registrar el destino de instalación como ubicación externa
Add-AppxPackage -Path "C:\Program Files\KomuraSoft\KomuraReport.identity.msix" `
                -ExternalLocation "C:\Program Files\KomuraSoft"

# Al desinstalar: anular el registro del paquete antes de borrar los archivos
Remove-AppxPackage <nombre completo del paquete>

Separar el registro para el usuario que ejecuta del despliegue para todos los usuarios

Add-AppxPackage se registra para el usuario que lo ejecutó. Si se ejecuta como LocalSystem desde una acción personalizada de un MSI per-machine, el usuario que instaló no obtiene identidad. Por eso se configura para ejecutarlo con suplantación (impersonate) del usuario.

Sin embargo, lo que se registra con la suplantación también es solo el usuario que ejecutó esa instalación. Si un mismo equipo lo usan varios usuarios, los demás y los usuarios creados después no tienen identidad de paquete, y el comando no aparece en el menú nuevo.

Si se quiere usar en todos los usuarios, se prepara un registro por usuario, por ejemplo comprobar el registro del propio paquete al primer arranque de la aplicación y, si no está, registrarlo. En la desinstalación, incluya también en el plan la anulación desde cada usuario que lo tenga registrado.

Si tras el registro no se refleja en el menú

Para que se aplique el registro del manifiesto, a veces hace falta reiniciar el Explorador (o cerrar sesión).6

Orden de registro y anulación de un sparse packageAl instalar se registra el sparse package después de colocar los archivos; al desinstalar se anula el registro antes de eliminarlos; atención a que el registro solo es válido para el usuario que lo ejecutóInstalaciónColocar los archivosRegistrar el sparse packageDesinstalaciónAnular el registro del paqueteEliminar los archivosEl registro solo es válido para el usuario que lo ejecutó

Figura 15: El registro va después de colocar los archivos y la anulación antes de eliminarlos; atención a que el registro es por usuario que lo ejecutó.

7.4. Limpieza al desinstalar — lo que se borra y lo que se deja

En la limpieza al desinstalar, la guía oficial tiene un criterio claro.1

  • Lo que se borra: el conjunto de claves ProgID propias, el registro de Capabilities/RegisteredApplications, el registro de CLSID de la extensión de shell, el sparse package (Remove-AppxPackage).
  • Lo que se deja: el valor predeterminado de la clave de extensión (.kmrpt). Aunque siga apuntando al ProgID propio, la recomendación oficial es no borrarlo. Es difícil juzgar si, tras la instalación, otra aplicación ha tomado el valor predeterminado, y Windows simplemente ignora un ProgID del valor predeterminado que no está registrado, de modo que dejarlo no hace daño real.
  • Al final de la limpieza también se llama SHChangeNotify(SHCNE_ASSOCCHANGED).

La mayoría de los problemas de «desinstalé y en el menú queda un resto» son fugas de este diseño de limpieza.

Diseño de la limpieza al desinstalarEn la desinstalación se borran las claves ProgID propias, el registro de CLSID y el sparse package; el valor predeterminado de la clave de extensión se deja porque un ProgID no registrado se ignora; al final de la limpieza se notifica el cambio con SHChangeNotifyDesinstalaciónLo que se borraLo que se dejaRegistro de ProgID o CLSIDsparse packageValor predeterminado de la clave de extensiónUn ProgID no registrado se ignoraAl final, notificar con SHChangeNotify

Figura 16: Se borra el registro propio, se deja el valor predeterminado de la clave de extensión y, al final de la limpieza, se notifica el cambio.

8. Resolución de problemas — no aparece, aparece duplicado, va pesado

Los fallos se investigan separándolos en «no aparece», «aparece duplicado o no desaparece» y «va pesado o se cae». Al final se explica cómo comprobar el registro y la limpieza en un entorno limpio.

8.1. No aparece en el menú

Primero confirme cuál de los dos menús, el nuevo o el antiguo, está mirando. Sobre esa base, aísle en este orden.

  1. Cuál de los dos menús está mirando: un registro al estilo antiguo solo aparece en el menú antiguo de Shift+F10. Confirme primero ambos.
  2. Bitness: una DLL de extensión de shell solo de 32 bits no se carga en el Explorador de 64 bits (sección 4.3).
  3. Destino de registro: confusión de HKLM/HKCU o Wow6432Node. Confirme la clave real con reg query.
  4. Registro del paquete: si es para el menú nuevo, confirme con Get-AppxPackage si está registrado, la confianza del certificado de firma y la ruta de -ExternalLocation, y reinicie el Explorador.6
  5. Notificación perdida: si se olvidó SHChangeNotify, se puede distinguir por si se aplica al reiniciar el Explorador.
Orden de aislamiento cuando no aparece en el menúEmpiece por confirmar cuál de los dos menús está mirando y aísle en el orden bitness de la DLL, destino de registro en el Registro, registro y firma del paquete, y notificación perdida de SHChangeNotifyConfirmar si es el menú nuevo o el antiguoConfirmar el bitness de la DLLConfirmar el destino de registro HKLM y HKCUConfirmar el registro y la firma del paqueteDistinguir una notificación perdida con un reinicio

Figura 17: Cuando «no aparece», aísle en el orden menú que está mirando, bitness, destino de registro, registro del paquete y notificación perdida.

8.2. Aparece duplicado o no desaparece

Primero, en cuál de los dos menús está duplicado da una pista.

  • Solo duplicado en el menú antiguo: sospeche una fuga de limpieza al desinstalar (sección 7.4) o un resto de un ProgID de una versión antigua.
  • Aparece en ambos, nuevo y antiguo: sospeche la coexistencia del registro en el Registro al estilo antiguo y del registro en el manifiesto MSIX.

En ambos casos es un aislamiento de causas típicas; decida confirmando el contenido real del registro.

Aislamiento de la aparición duplicadaSi solo está duplicado en el menú antiguo, la pista es resto o fuga de limpieza o un ProgID antiguo; si aparece en ambos, nuevo y antiguo, la pista es la coexistencia del registro en el Registro al estilo antiguo y del registro en el manifiestosolo el menú antiguoambos, nuevo y antiguo¿En cuál está duplicado?Familia de restosFamilia de coexistenciaFuga de limpieza o resto de un ProgID antiguoCoexistencia del registro antiguo en el Registro y del nuevo

Figura 18: Si solo está duplicado en el menú antiguo, familia de restos; si aparece en ambos, familia de coexistencia.

8.3. El Explorador va pesado o se cae

Si el clic derecho es lento o se bloquea en una carpeta concreta, primero haga inventario de las extensiones de shell instaladas.

  1. Listar las extensiones. Con una herramienta como ShellExView de NirSoft, confirme las que no son de Microsoft.
  2. Deshabilitarlas temporalmente y reducir. Haga una búsqueda binaria de las sospechosas e identifique la DLL causante. Si hay un bloqueo, el «módulo en el que se produjo el error» del Visor de eventos también es una pista.
  3. Si es una extensión propia, investigue la ruta de construcción del menú. Sospeche E/S síncrona o acceso de red (secciones 4.2 y 5.2).
Identificación de la DLL causante cuando va pesado o se caeListar las extensiones de shell que no son de Microsoft con ShellExView, deshabilitar temporalmente las sospechosas y hacer una búsqueda binaria para identificar la DLL causante; si hay un bloqueo, el módulo de error del Visor de eventos también es una pistaInventario de extensiones de shellListar las que no son de MicrosoftDeshabilitar temporalmente y búsqueda binariaIdentificar la DLL causanteSi hay un bloqueoConfirmar el módulo de error

Figura 19: Deshabilite temporalmente las extensiones que no son de Microsoft y haga una búsqueda binaria; si hay un bloqueo, combine también el Visor de eventos.

8.4. Para la verificación, Windows Sandbox es cómodo

La verificación de la integración con el shell se basa en confirmar «en un entorno limpio, instalar → funcionar → desinstalar → cero restos». Aquí es cómodo Windows Sandbox (Pro/Enterprise/Education): cada arranque levanta en unos segundos un Windows desechable de cero, de modo que se puede repetir las veces que haga falta la prueba de registro y limpieza del instalador. Al cerrarlo todo desaparece, así que también sirve para investigar restos del Registro.15

9. Resumen

Si al pasar a Windows 11 le dicen que «el menú se ha escondido», confirme primero en la tabla de decisión del capítulo 6 qué quiere lograr. El orden de pensamiento es estas tres etapas.

1. Decidir si basta la asociación

Si solo es «abrir con esta aplicación», siguen bastando la asociación y el verb estático. La base es clave de extensión → ProgID → verb, y HKCR es una vista de comprobación que superpone Classes de HKLM/HKCU. Indique el destino de escritura y entrecomille siempre %1.

Sin embargo, quien elige la aplicación predeterminada es el usuario. El instalador no arrebata el valor predeterminado: se registra correctamente como candidato.

2. Decidir en cuál de los dos menús poner el comando propio

Una extensión IContextMenu tradicional funciona en el menú antiguo que se abre con «Mostrar más opciones». Para poner un comando propio en el menú nuevo hacen falta IExplorerCommand y el registro en el manifiesto MSIX. Para una aplicación que no se puede pasar por completo a MSIX, la respuesta realista es obtener identidad de paquete con un sparse package.

La DLL de una extensión tradicional se ejecuta dentro del proceso del Explorador y similares. Un bloqueo o un retraso se propagan a todo el host, y un host de 64 bits necesita una DLL de 64 bits. Escribir una extensión en proceso en código administrado no tiene soporte; la implementación en C++ nativo es el principio.

3. Verificar juntos el registro, la notificación de cambio y la anulación

Tras registrar, cambiar o eliminar una asociación, se notifica con SHChangeNotify. En la desinstalación se borra el ProgID propio y similares, y se deja el valor predeterminado de la clave de extensión. Un sparse package es un registro por usuario, así que en un entorno de varios usuarios incluya también en el plan el registro y la anulación de cada usuario.

Con Windows Sandbox, repita en un entorno limpio instalar → funcionar → desinstalar → confirmar restos.

Elegir desde el medio más simple y, solo si hace falta, avanzar a añadir un comando propio al menú nuevo. Con este orden se ordenan la escala de la respuesta y el alcance del registro y de la implementación que hay que mantener.

Artículos relacionados

Áreas de consultoría relacionadas

KomuraSoft LLC se ocupa del diseño e implementación de la asociación de archivos, el menú contextual y las extensiones de shell de aplicaciones de negocio, de la adaptación al nuevo menú contextual de Windows 11 (paso a IExplorerCommand, introducción de sparse package), de la revisión del registro y la limpieza de un instalador existente, y de la investigación de causas cuando el Explorador va pesado o se cae. Puede consultar ya desde la decisión de política de «qué hacer con el menú que se ha escondido en Mostrar más opciones».

Referencias

  1. Microsoft Learn, File Types. La estructura en la que la clave de extensión apunta a un ProgID, OpenWithProgIds, el uso diferenciado del registro en HKLM/HKCU\Software\Classes, que tras cambiar una asociación hay que llamar SHChangeNotify(SHCNE_ASSOCCHANGED), y que al desinstalar se elimina el ProgID dejando el valor predeterminado de la clave de extensión. ↩ ↩2 ↩3 ↩4 ↩5

  2. Microsoft Learn, Choosing a Static or Dynamic Shortcut Menu Method. Que hay que elegir el método de verb estático más simple que cubra el requisito, que IContextMenu es el más potente pero también el más complejo y se clasifica del lado no recomendado, y que IExplorerCommand/IExplorerCommandState es el método recomendado. ↩ ↩2

  3. Microsoft Learn, HKEY_CLASSES_ROOT Key. Que HKEY_CLASSES_ROOT es una vista que compone HKLM\Software\Classes y HKCU\Software\Classes, que la definición del lado del usuario tiene prioridad sobre la del lado de la máquina, y las reglas de reparto al escribir. ↩ ↩2

  4. Microsoft Learn, Windows app defaults platform. Que el cambio de la aplicación predeterminada está diseñado para hacerse solo a través de la interfaz de configuración del sistema, que los datos de configuración del usuario están ofuscados y protegidos contra escritura por un controlador de filtro (UCPD.sys), que un cambio basado en el Registro no tiene soporte, y que en un entorno administrado se usa Directiva de grupo o una directiva MDM. ↩ ↩2

  5. Windows Developer Blog, Extending the Context Menu and Share Dialog in Windows 11. El diseño del nuevo menú contextual de Windows 11, la extensión con IExplorerCommand e identidad de aplicación, la colocación superior de «Abrir» y «Abrir con», la reunión de varios comandos en un flyout con el nombre de la aplicación, y que una extensión IContextMenu tradicional se carga como el menú de Windows 10 de «Mostrar más opciones» (Shift+F10). ↩ ↩2 ↩3

  6. Microsoft Learn, Add a File Explorer context menu command to a packaged desktop app. Que el registro en el nuevo menú contextual de Windows 11 se hace con una implementación de IExplorerCommand y las declaraciones de manifiesto windows.comServer y desktop4:FileExplorerContextMenus, que en ItemType se pueden especificar *, Directory y Directory\Background, la coincidencia de arquitectura de la DLL, mantener rápidos los métodos de construcción del menú, la respuesta de una aplicación no empaquetada con sparse package, que a veces hace falta reiniciar el Explorador para que se aplique el registro, y que la asociación de archivos no es una extensión de menú de uso general. ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8

  7. Microsoft Learn, Grant package identity by packaging with external location. Que se puede obtener identidad de paquete registrando un paquete con ubicación externa (sparse package) sin cambiar el instalador existente, que está disponible desde Windows 10 versión 2004, y que se pueden usar funciones de Windows que exigen identidad (registro en el menú contextual, notificaciones, etc.). ↩ ↩2 ↩3

  8. Microsoft Learn, Working with Shell Extensions. Los tipos de controlador de extensión de shell, que la extensión es una DLL COM en proceso que se carga en el Explorador (y en un proceso que hospeda el shell) y que un bloqueo o un cuelgue se propagan a todo Explorer, el registro con ThreadingModel=Apartment, y que hay que estudiar primero un medio alternativo más simple que una extensión de shell. ↩ ↩2 ↩3

  9. Microsoft Learn, Guidance for Implementing In-Process Extensions. Que Microsoft no recomienda y deja fuera de soporte la implementación de una extensión de shell en proceso en código administrado, las razones de conflicto de versión del CLR, reentrada y falta de determinismo de la vida de los objetos, y que en una extensión fuera de proceso (controlador de vista previa o arranque desde shell\verb\command) el código administrado sí se admite. ↩ ↩2 ↩3

  10. Microsoft Learn, SHChangeNotify function. El método de emitir el evento SHCNE_ASSOCCHANGED para notificar al sistema un cambio de asociación de archivos, y el uso para que el shell reconozca el cambio. ↩ ↩2

  11. Microsoft Learn, Application Registration. Que se recomienda el registro del archivo ejecutable con la subclave App Paths, el papel de la subclave Applications, el registro de verb con SystemFileAssociations, y el orden de prioridad del ProgID y de la información relacionada al cambiar la aplicación predeterminada. ↩

  12. Microsoft Learn, Creating Shortcut Menu Handlers. El método de registro de un verb estático, el orden de decisión del verb predeterminado (valor predeterminado → primer verb → Open → Open With), que el nombre mostrado de un verb estándar lo suministra el SO, el verb extendido con Extended, que la asociación con un comando DDE está en desuso (Deprecated), y la precaución de la redirección WOW64 en un entorno de 64 bits. ↩ ↩2 ↩3

  13. Microsoft Learn, Verbs and File Associations. Que el verb es un verbo que también usa ShellExecuteEx, que un elemento de la cadena de comando que puede incluir un espacio hay que entrecomillarlo y “%1” debe escribirse siempre con comillas, y el registro del procedimiento predeterminado bajo HKCR\Applications. ↩

  14. Microsoft Learn, IExplorerCommand interface. La composición de métodos GetTitle, GetIcon, GetState, Invoke, EnumSubCommands, etc., que los métodos se llaman en el hilo de la interfaz y no deben comunicar con un recurso de red, y que está disponible desde Windows Vista. ↩

  15. Microsoft Learn, Windows Sandbox. Que se puede arrancar en unos segundos un entorno Windows aislado y desechable, que al cerrarlo se descartan todos los cambios, que sirve para probar software y verificar un instalador, y que está disponible en Pro/Enterprise/Education. ↩

Artículos recientes con las mismas etiquetas para profundizar en temas cercanos.

Estas páginas sitúan el tema en un contexto más amplio de servicios y decisiones.

El artículo está directamente relacionado con los siguientes servicios.

Preguntas frecuentes

Preguntas habituales en las consultas sobre el tema del artículo.

¿Por qué el menú contextual de nuestra aplicación en Windows 11 solo aparece dentro de «Mostrar más opciones»?
Porque en Windows 11 el menú contextual del Explorador se dividió en dos niveles, uno nuevo y uno antiguo. Solo pueden aparecer en el menú nuevo los comandos que implementan la interfaz IExplorerCommand y se registran en el manifiesto de un paquete MSIX (es decir, que tienen identidad de paquete); las extensiones de shell tradicionales basadas en IContextMenu se relegaron al menú antiguo que se abre con «Mostrar más opciones» (Shift+F10). La extensión en sí no se ha roto, así que de momento sigue funcionando, pero si se quiere que aparezca en el menú nuevo hace falta migrar a IExplorerCommand y otorgarle identidad con MSIX o un sparse package.
¿Puede el instalador configurar nuestra aplicación como la aplicación predeterminada del archivo (la que lo abre con doble clic)?
No. La elección de la aplicación predeterminada está diseñada para que la haga el usuario, y Windows no admite cambiarla desde ningún sitio que no sea la interfaz de configuración del sistema. La información de UserChoice que conserva la elección de cada usuario está ofuscada, y un controlador de filtro (UCPD.sys) también bloquea las escrituras desde las aplicaciones. Lo que el instalador puede hacer es registrar el ProgID y el verb, añadirse a OpenWithProgIds para figurar como candidato en «Abrir con» e inducir al usuario a la pantalla de configuración de aplicaciones predeterminadas. La implementación correcta no es arrebatar el valor predeterminado, sino preparar la aplicación para ser elegida.
¿Se puede escribir una extensión de shell en código administrado, como C#?
Microsoft afirma de forma explícita que escribir en código administrado una extensión de shell que se carga en proceso (un controlador de menú contextual, un controlador de iconos, etc.) no es recomendable y no tiene soporte. La extensión se carga en el proceso del Explorador o de cualquier aplicación que abra un cuadro de diálogo de archivos común, de modo que los conflictos de versión del CLR, la reentrada y la falta de determinismo en la vida de los objetos desestabilizan la aplicación anfitriona. La regla es implementarlas en C++ nativo. En cambio, un EXE normal iniciado por el command de un verb, o una extensión fuera de proceso que corre en otro proceso, como un controlador de vista previa, no tiene problema en código administrado.
¿Qué es un sparse package (MSIX con ubicación externa)?
Un paquete MSIX pequeño que no incluye los archivos de la propia aplicación, sino solo el manifiesto (información de identidad). Si a una aplicación instalada con normalidad con un instalador existente (MSI, Inno Setup, etc.) se le registra un sparse package apuntando con -ExternalLocation de Add-AppxPackage a la carpeta de instalación, esa aplicación obtiene identidad de paquete y puede usar funciones que la requieren, como el registro en el nuevo menú contextual de Windows 11 o las notificaciones toast. Está disponible desde Windows 10 versión 2004 y el paquete necesita una firma de código de confianza en el equipo de destino. Es la opción realista cuando se quiere el menú nuevo sin migrar por completo la distribución a MSIX.
¿Qué hago si un elemento del menú contextual aparece duplicado o no desaparece?
Primero aísle la causa comprobando en cuál aparece: el menú nuevo o el antiguo (Mostrar más opciones). La aparición duplicada suele deberse a que coexisten el registro tradicional del Registro y el registro en el manifiesto MSIX, o a que, al desinstalar, quedaron sin limpiar el ProgID o el registro de CLSID de la extensión. Tras cambiar una asociación, sospeche también una notificación perdida de SHChangeNotify (SHCNE_ASSOCCHANGED); justo después de registrar el paquete, que falte reiniciar el Explorador. Si aun así no se resuelve, deshabilitar temporalmente las extensiones que no son de Microsoft con ShellExView y aplicar una búsqueda binaria permite identificar la DLL causante.

Perfil del autor

Página de presentación del autor del artículo.

Go Komura

Representante de KomuraSoft LLC

Especializado en desarrollo de software para Windows, consultoría técnica e investigación de fallos, sobre todo en proyectos con sistemas existentes y errores difíciles de reproducir.

Volver al blog