c++ dll wix windows-installer wix3.10

c++ - Registrar un dll de CPP en COM después de la instalación utilizando el instalador Wix Msi



windows-installer wix3.10 (3)

Respuesta breve y resumida

Debe dejar de usar archivos por lotes y acciones personalizadas para el registro COM (poco confiable) y, en su lugar, extraer la información de registro COM utilizando la herramienta heat.exe del kit de herramientas WiX para agregar el registro COM a su base de datos MSI en el momento de la compilación.

Hay algunas complicaciones para los binarios de 64 bits, consulte los detalles a continuación. Afortunadamente, parece que se trata de un componente de 32 bits basado en el directorio de instalación que se muestra arriba.

En este caso particular, ayudó a ejecutar heat.exe en el archivo COM después de la implementación cuando todas las dependencias estaban "en su lugar" para que el archivo COM se cargara correctamente. Hay muchas "comunicaciones de depuración" en estas respuestas. Dejaré todo en su lugar para el futuro, pero primero intente esta solución simple. Y quizás pruebe la nueva herramienta de dependencia "Dependencies.exe" que se describe a continuación.

Respuesta larga y detallada

Antes de intentar responder la pregunta (que parece girar en torno a las dependencias faltantes o algo extraño que se está haciendo en su archivo por lotes ), quiero aclarar algunas cosas para usted con respecto a las mejores prácticas para el registro COM.

Nota : la captura de pantalla parece indicar que algo extraño está sucediendo en su archivo por lotes, pero las dependencias faltantes aún podrían ser un problema.

Autorregistro considerado perjudicial

El autorregistro no debe usarse para registrar archivos COM . Aquí hay una descripción de por qué este es el caso: MSI register dll - Auto-registro considerado dañino . Sin embargo, hay buenas noticias, hacer las cosas según lo previsto a través de los mecanismos MSI incorporados será más fácil y más confiable una vez que lo haya configurado correctamente.

Hay una manera de auto-registrar archivos durante la instalación sin usar acciones personalizadas como está tratando de hacer ( la tabla SelfReg ). Es muy difícil que las acciones personalizadas funcionen correctamente, pero tampoco debe usar el mecanismo incorporado para ejecutar el registro automático (como se explica en detalle en la respuesta vinculada anteriormente)

En lugar de utilizar acciones personalizadas o la tabla SelfReg, la información de registro COM debe extraerse de sus archivos COM en el momento de la compilación , en otras palabras, cuando compila su archivo MSI de sus archivos fuente WiX. Los datos de registro extraídos deben usarse para llenar la familia de tablas de datos MSI diseñadas para registrar y cancelar el registro del archivo COM de manera confiable durante la instalación y desinstalación, respectivamente.

WiX: la herramienta de línea de comandos "heat.exe"

No es necesario comprender los intrincados detalles de este proceso; todo lo que necesita saber es qué herramientas utilizar. WiX proporciona la herramienta " heat.exe " para este propósito. Es esencialmente una herramienta " recolectora " capaz de generar archivos fuente WiX XML válidos para varios propósitos, uno de los cuales es la extracción COM. También admite directorios de recorrido en general, generando archivos fuente WiX que pueden instalar los archivos encontrados durante el recorrido. Es esencialmente una forma muy rápida de hacer un paquete MSI una vez que sepa cómo usarlo.

Caminante de dependencia

Por lo tanto, hemos establecido que debe tomarse el tiempo para aprender a usar heat.exe para generar la fuente de WiX necesaria para registrar el archivo COM correctamente. Sin embargo, hay un problema más : las dependencias que faltan .

Para que un archivo COM pueda registrarse automáticamente, o para que pueda extraer con éxito los datos del registro COM utilizando heat.exe, el archivo COM debe poder cargarse correctamente. Para que esto sea posible, todas las dependencias dll deben estar disponibles en el sistema en cuestión en una ubicación accesible.

Obtenga una copia de Dependency Walker y úsela para escanear su archivo COM en busca de los archivos de los que depende. Aquí hay un ejemplo de un archivo COM que no se carga porque no puede encontrar MMUtilities.dll :

Lo más probable es que encuentre algo similar mal con su dll (o cualquier tipo de archivo que sea, por ejemplo OCX) cuando se ejecuta desde la ubicación de instalación de su configuración. Regsvr32.exe no puede encontrar los archivos de dependencia necesarios y el proceso de registro falla.

Hay algunas dependencias faltantes informadas que no son importantes . Supongo que esto tiene que ver con la antigüedad de la herramienta Dependency Walker. Hasta donde yo sé, no se ha actualizado recientemente. Busque un archivo que reconozca como su propio archivo de dependencia o un archivo de sistema central en lugar de nombres dll muy largos de archivos de los que nunca ha oído hablar. Tenga en cuenta que algunos archivos DLL tienen archivos DLL de idioma de dependencia necesarios para la carga. Por ejemplo, MMUtilities.dll necesita MmUtilitiesEnglish.dll u otro dll de idioma presente en la misma carpeta para poder cargarse correctamente.

Algunas dependencias de falsos positivos para el archivo anterior: API-MS-WIN-CORE-RTLSUPPORT-L1-1-0.DLL , API-MS-WIN-CORE-PROCESSTHREADS-L1-1-0.DLL , API-MS-WIN-CORE-REGISTRY-L1-1-0.DLL , etc ... Hubo muchos. Creo, pero no estoy seguro, que la causa raíz de estos falsos positivos se centra en los problemas con los componentes uno al lado del otro instalados en la carpeta WinSxS, pero esa es otra discusión: solo mencionarlo.

ACTUALIZACIÓN : Acabo de comprobar esto nuevamente y la mayoría de las dependencias de falsos positivos que se ven arriba son aparentemente API-sets , una característica de Windows introducida mucho después de que se creó Dependency Walker y, por lo tanto, la herramienta no la maneja correctamente.

Como indica la respuesta vinculada (léalo, enlace anterior), ahora también hay una reescritura de Dependency Walker en C # llamada " Dependencias ", disponible aquí: https://github.com/lucasg/Dependencies (no probado por mí en ese momento de escritura, lo probaré en breve).

También mención rápida: si tiene un ejecutable para verificar (a diferencia de un dll, ocx, etc ...), puede iniciarlo a través de la entrada del menú Profile => Start Profiling... y también verá " oculto dependencias de tiempo de ejecución "no especificado en la tabla de importación binaria (donde se especifican las dependencias / importaciones). Debe ejercer realmente la aplicación utilizando todas las funciones en todos los cuadros de diálogo para asegurarse de obtener todas esas dependencias.

La página web del caminante de dependencias llama a estas dependencias ocultas dependencias explícitas (una dependencia dinámica o de tiempo de ejecución) y dependencias de enlace del sistema (dependencias inyectadas). Vea el enlace de arriba para más detalles.

Extracción Heat.exe

Una vez que haya determinado qué archivos faltan para que su extracción de WiX heat.exe funcione, puede colocar los archivos en cuestión "al lado" de su dll COM para que se encuentren durante su carga. Puede probar la ejecución con regsvr32.exe para ver si el registro se completa correctamente. No debería haber mensajes de error cuando ejecuta el registro manualmente de esta manera. Recuerde ejecutar el registro desde un símbolo del sistema elevado .

Varias otras respuestas de stackoverflow explican cómo usar heat.exe: no lo he usado en mucho tiempo: cómo ejecutar heat.exe y registrar un dll en wix . Aquí está la documentación oficial para heat.exe de los propios chicos de WiX. Puede ser una herramienta un tanto intimidante: tiene muchas características.

En su forma más simple (para archivos COM normales de 32 bits con todas las dependencias disponibles en la ruta o carpeta local), puede ejecutar esta línea de comando heat.exe para generar un archivo fuente de salida WiX llamado YourFileName.wxs con todo el registro COM requerido datos.

heat.exe file YourFileName.ocx -o YourFileName.wxs

Hace varios años escribí una respuesta que mostraba cómo incorporar los datos de registro de WiX exportados en su fuente principal de WiX: Cómo hacer referencia a una salida de calor (wxs) en Wix (línea de comandos) . Creo que esta es una descripción precisa del procedimiento, pero por alguna razón alguien rechazó la respuesta. Inténtalo y comprueba si te funciona.

¡Importante! : heat.exe aún no procesa correctamente los binarios COM de 64 bits (diciembre de 2017).

Me han informado que el paquete de expansión WiX ( no gratuito ) maneja binarios de 64 bits y ofrece varias otras características. Supongo que puedo vincularlo (no estoy afiliado con FireGiant): https://www.firegiant.com/wix/wep-documentation/harvesting/ . De alguna manera, la gente necesita saber sobre estas cosas, pero no estoy seguro acerca de la etiqueta de enlace de stackoverflow.

¿Son sus binarios de 64 bits? (no se ve así desde su carpeta de instalación, pero agrego esto para otros que puedan encontrarlo). Para un componente de 64 bits, supongo que hemos cerrado el círculo y tenemos que aconsejarle que use la función del paquete de expansión anterior o simplemente intente configurar el archivo para que se registre automáticamente como se describe aquí . Odio esta "solución" de autorregistro, pero no puedo pensar en ninguna otra solución rápida en este momento (ninguna que recomendaría de todos modos). Revisaré nuevamente. Asegúrese de verificar la última versión de WiX para ver si el problema de 64 bits se ha solucionado antes de buscar esta "solución de autorregistro" . Es al menos mejor que tratar de registrarse usando acciones personalizadas y archivos por lotes (que nunca deberían intentarse; hay tantos problemas potenciales relacionados con la secuencia de acciones personalizadas complejas de MSI, suplantación / elevación, condicionamiento, modos de instalación con silencioso e interactivo, no mencionar la posible interferencia del software de seguridad, y la lista continúa).

Algunos enlaces:

Estoy tratando de registrar una biblioteca CPP en COM durante la instalación de Msi.

He buscado mucho y he encontrado muchas soluciones aquí, pero nada funciona en mi código. No sé si hay algún método directo para esto. He intentado usar Acción personalizada con ExeCommand directo y con un script por lotes.

Aquí está el código con script por lotes.

<SetProperty Id="Register" Value="&quot;[INSTALLDIR]Scripts/Register.bat&quot;" After="CostFinalize"/> <CustomAction Id="Register" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no"/> <SetProperty Id="Unregister" Value="&quot;[INSTALLDIR]Scripts/UnRegister.bat&quot;" After="CostFinalize"/> <CustomAction Id="Unregister" BinaryKey="WixCA" DllEntry="CAQuietExec" Execute="deferred" Return="check" Impersonate="no"/>

Usando este código, la instalación no muestra ningún error, pero dll no se está registrando. Después de la instalación, si ejecuté el script por lotes por separado, entonces se registra.

Register.bat

cd "C: / Windows / System32"

regsvr32 "C: / Archivos de programa (x86) / ABC / Abc.dll"

ping -n 15 127.0.0.1> nul:

Anular registro.bat

cd "C: / Windows / System32"

regsvr32 / u "C: / Archivos de programa (x86) / ABC / Abc.dll"

ping -n 15 127.0.0.1> nul:

Con Acción personalizada con ExeCommand, muestra un error como falta alguna dependencia dll. El código ExeCommand se da a continuación.

<CustomAction Id="Register" Directory="INSTALLDIR" Execute="deferred" Impersonate="no" ExeCommand="[WindowsFolder]System32/regsvr32 &quot;[INSTALLDIR]Abc.dll&quot;" Return="check" /> <CustomAction Id="Unregister" Directory="INSTALLDIR" Execute="deferred" Impersonate="no" ExeCommand="[WindowsFolder]System32/regsvr32 /u &quot;[INSTALLDIR]Abc.dll&quot;" Return="check" />

A continuación, se proporciona InstallSequence para ambos casos.

<InstallExecuteSequence> <Custom Action="Register" Before="InstallFinalize" >NOT Installed</Custom> <Custom Action="Unregister" Before="RemoveFiles">Installed AND NOT UPGRADINGPRODUCTCODE</Custom> </InstallExecuteSequence>

En ambos casos, creo que se está ejecutando con privilegios elevados.

Este es el error que recibo la mayor parte del tiempo.

Editar

La vista del caminante de dependencia de la dll se muestra a continuación.

También estoy agregando el comando de calor que utilicé. He agregado esto al evento prebuild para generar el componente. Después de eso agregó este componente en el archivo del producto.

llame al archivo "$ (WIX) bin / heat.exe" "dllPath / Abc.dll" -dr "INSTALLDIR" -srd -gg -sfrag -suid -out "$ (SolutionDir) Installer / ComRegisterComponent.wxs"

Y el archivo generado se ve así.

<Fragment> <DirectoryRef Id="INSTALLDIR"> <Component Id="Abc.dll" Guid="*"> <File Id="Abc.dll" KeyPath="yes" Source="SourceDir/Abc.dll" /> </Component> </DirectoryRef> </Fragment>

Aquí esta ruta de SourceDir me está confundiendo. He agregado la ruta exacta en el comando de calor incluso cuando genera este SourceDir.


La idea es no usar un archivo bat para registrar el dll. Deje que el instalador de Windows / WiX lo haga por usted. Esto ha sido respondido en el pasado también aquí .


Simplemente agregue otra respuesta con información sobre cómo usar procmon.exe de manera eficiente para depurar las dependencias que faltan durante el auto registro utilizando regsvr32.exe .

Esencialmente, debe establecer un filtro de inclusión para los eventos que desea monitorear y registrar, de lo contrario obtendrá una lista todopoderosa de eventos irrelevantes enumerados y es difícil encontrar lo que necesita en el mar de información inútil:

  1. Para limitar la información del proceso capturado a lo que necesita, simplemente vaya a Filter => Filter...
  2. Establezca el menú desplegable de la izquierda en Process Name y luego la segunda columna is y finalmente escriba regsvr32.exe en el cuadro de la derecha como se ilustra arriba en la imagen.
  3. Establezca crucialmente el cuadro de la derecha para Include . Luego presione OK.
  4. Todos los eventos innecesarios ahora deben suprimirse y solo se muestran los eventos regsvr32.exe (cuando puede ejecutarlo).
  5. Ejecute regsvr32.exe la manera normal y busque entradas " NAME NOT FOUND " (o similar) en la lista.
  6. En la siguiente ilustración no se puede encontrar MMUtilities.dll . En otras palabras, es una dependencia que falta.

Y tenga en cuenta que puede incluir / excluir eventos de cierto tipo haciendo clic en los botones que se ilustran a continuación. Registry events , Registry events file system events , network activity , network activity process and tread activity , profiling events . Esto puede reducir en gran medida el "ruido" con el que tiene que lidiar en la lista.

La otra forma de depurar las dependencias que faltan durante el auto registro es usar Dependency Walker como se ilustra en mi otra respuesta en este "hilo" o pregunta o como se llame. En general, creo que Dependency Walker es la opción más rápida, pero procmon.exe es quizás mejor en general, a menos que esté depurando un archivo EXE, entonces Dependency Walker tiene la característica de Profile superior ( Profile => Start Profiling... ).