¿Cómo escribir una extensión de shell en C++?
atl windows-shell (1)
No puedo decirte exactamente cómo escribir una extensión de shell, pero te daré una serie de consejos. Escribir una extensión de Shell ofrece algunas ventajas significativas sobre el método mucho más simple de "solo registro":
- Con una Extensión de Shell, puede crear dinámicamente un elemento del menú de contexto (o submenú) que sea más relevante para los archivos seleccionados. Por ejemplo, si está escribiendo una extensión de Shell para archivos zip, es posible crear un submenú dentro del menú contextual que muestra todo el contenido del archivo zip.
- Puede manejar múltiples archivos a la vez, lo que puede ser más beneficioso no solo para fines de rendimiento sino también para que pueda determinar qué hacer en función de la selección en su conjunto y no solo para cada archivo.
Algunas de las caídas de las extensiones de Shell son:
Substancialmente mayor complejidad. Esté preparado para hacer un gran esfuerzo en esto para que funcione. Instale una máquina de café espresso junto a su computadora y / o contrate a alguien para que le prepare café.
Substancialmente mayor dificultad en la depuración. Lo mismo ocurre con el café.
Es difícil escribir una extensión de shell porque pueden ser muy difíciles de depurar.
Las extensiones de Shell se cargan mediante el proceso
explorer.exe
, y sin la configuración específica de Explorer, debe forzar la salida del proceso deexplorer.exe
para poder instalar una versión más nueva de su Extensión de Shell. Hay una manera de hacer que Explorer descargue los DLL que ya no usa, pero solo debe hacerlo en una máquina de desarrollo y no en un destino de implementación:En RegEdit, busque la siguiente clave:
HKEY_LOCAL_MACHINE / SOFTWARE / Microsoft / Windows / CurrentVersion / Explorer
Agregue una nueva clave DWORD llamada "AlwaysUnloadDLL" y establezca su valor en 1.
- Reinicie el explorador.
Esto funciona la mayoría de las veces, pero aún puede haber ocasiones en las que necesite cerrar Explorer porque la extensión de Shell no se descargó.
Tenga en cuenta que otras aplicaciones pueden cargar su Shell Extension, por ejemplo, si hace clic con el botón derecho en un archivo con el cuadro de diálogo "abrir archivo" de aplicaciones, entonces se cargará su Shell Extension en esa aplicación y no en Explorer.
- Si su Extensión de Shell causa un error de tiempo de ejecución, muy a menudo el resultado será simplemente que su elemento del menú contextual no se muestra, muy rara vez se le dirá que su Extensión de Shell no se cargó o que causó un error de tiempo de ejecución.
- La configuración puede ser difícil, incluso con una instalación, los datos de registro deben crearse en varios lugares y, dependiendo de dónde desee que se muestre su menú contextual, los lugares en el registro pueden diferir entre las diferentes versiones de Windows.
Lo que necesitarás hacer:
- Visual Studio ofrece algunos accesos directos para crear extensiones de Shell, pero básicamente necesitará crear una DLL COM. Una extensión de Shell para los elementos del menú contextual debe implementar tanto la interfaz
IContextMenu
como la interfazIShellExtInit
. - En el
IShellExtInit::Initialize()
, puede obtener los archivos seleccionados del parámetroIDataObject
. Desde la memoria, los datos están en el formato "Arrastrar y soltar", por lo que necesita obtener un controladorHDROP
delIDataObject
y consultar los archivos desde allí (esto es de la memoria, en realidad puede ser diferente al que describí aquí). así que proceda con precaución). - Una vez que su DLL esté lista para ser "instalada", debe copiarla en algún lugar y luego ejecutar
regsvr32
para asegurarse de que esté registrada. - Siga esta guía para saber dónde colocar las claves de registro.
- Puede haber problemas con Windows de 64 bits. Si crea una DLL de 32 bits, puede que no se cargue en el Explorador de 64 bits ... así que tenga esto en cuenta si tiene problemas con Windows de 64 bits.
- Su DLL realmente tendrá dos GUID asociados con él. No puedo recordar exactamente cómo funciona, pero un GUID se refiere a la propia DLL y el otro se refiere a la extensión de Shell real. Asegúrese de usar el GUID de la extensión de Shell real al crear claves en el registro donde se requiere un GUID.
Todas las cosas consideradas ... (tl; dr)
Sopesar los costos de si una extensión de Shell vale la pena. Si desea crear elementos de menú de forma dinámica en función de los archivos seleccionados, entonces una Extensión de Shell puede ser la única manera. Si desea manejar todos los archivos simultáneamente, probablemente también necesite una extensión de Shell.
Una alternativa al método del menú contextual, podría ser tener un objetivo de arrastrar y soltar en el escritorio del usuario o algo así. Explore otras formas en las que podría hacer que el usuario envíe sus archivos a su aplicación, porque una extensión de Shell a menudo es mucho más esfuerzo de lo que vale. Descubrí esto por el camino difícil y creo que todos los demás también lo han hecho.
Esto parecía una pregunta común, pero después de buscar un poco, no pude encontrar mis respuestas. Hay un artículo sobre esto aquí:
http://www.codeproject.com/KB/shell/shellextguide1.aspx
Pero es para una versión muy antigua de Visual Studio. Estoy usando VS 2008, por lo que las instrucciones y las interfaces no parecen coincidir con lo que estoy viendo.
Quiero crear una extensión de shell simple utilizando C ++ que cree un menú contextual para archivos con extensión .GZ. Al hacer clic derecho en estos archivos, debería poder hacer clic en mi elemento del menú contextual y tener una devolución de llamada en el código para realizar algún tipo de operación en ese archivo.
Otros elementos del menú contextual harían cosas como generar cuadros de diálogo sin modulación para aceptar la entrada del usuario antes de ejecutar alguna acción.
Por lo que he visto, ATL se usa para esto, pero nunca he usado ATL, por lo que todos los tipos de objetos e interfaces son muy confusos para mí. No sería tan malo si tuviera un tutorial adecuado o documentación para leer.
¿Puede alguien ayudarme? ¿No hay algún tipo de tutorial por ahí que no tenga 10 años?