2009-03-24 11 views
13

Usamos wix para crear configuraciones para nuestra aplicación. Para el caso en el que el usuario ya ha instalado una versión anterior de nuestra aplicación, realizamos una actualización importante con el MajorUpgrade XML element. Todo esto funciona como se desea: si se instala una versión anterior, se actualiza de forma transparente. Si hay una versión más reciente, el instalador cancela con un mensaje claro.¿Cómo puedo arreglar la lógica de actualización de una configuración wix después de cambiar InstallScope a "perMachine"

Sin embargo, ahora quiero cambiar el InstallScope de "perUser" a "perMachine". Desafortunadamente esto rompe la lógica de actualización. El nuevo instalador no parece detectar y eliminar la instalación previa "perUser". En cambio, simplemente se instala encima de la versión anterior en la misma ubicación de ProgramFiles. El usuario puede ver dos entradas en la lista "agregar/eliminar programas" y ve dos accesos directos idénticos en el escritorio (el antiguo específico del usuario y el nuevo perMachine).

¿Cómo paso mi instalador del ámbito de instalación "perUser" al de "perMachine" sin romper la lógica de actualización?

Respuesta

5

Comenzando con la configuración por equipo.

<Property Id="ALLUSERS" Value="1" /> 

Esto ejecutará un sistema automático de verificación por equipo (si tiene el elemento MajorUpgrade de trabajo, supongo), que no se levante el anterior usuario por instalación:

Action start 15:46:35: FindRelatedProducts. 
MSI (c) (D0:0C) [15:46:35:496]: FindRelatedProducts: current install is per-machine. Related install for product '{0C6604FB-58EC-48B9-8259-5871EFDADEB9}' is per-user. Skipping... 
MSI (c) (D0:0C) [15:46:35:496]: FindRelatedProducts: current install is per-machine. Related install for product '{0C6604FB-58EC-48B9-8259-5871EFDADEB9}' is per-user. Skipping... 

Así que antes instalar, asegúrese de ejecutar otra FindRelatedProducts llamada para los productos que se han instalado en el ámbito de usuario (por ejemplo, como este):

<!-- temporarily switch to per-user install scope--> 
<Publish Dialog="MyWelcomeDlg" Control="Next" Property="ALLUSERS" Value="{}">1</Publish> 
<!-- find related products that have been installed per-user --> 
<Publish Dialog="MyWelcomeDlg" Control="Next" Event="DoAction" Value="FindRelatedProducts">1</Publish> 
<!-- switch back to per-machine install scope--> 
<Publish Dialog="MyWelcomeDlg" Control="Next" Property="ALLUSERS" Value="1">1</Publish> 

esto a su vez se encuentra la instalación por usuario:

Action start 15:46:36: FindRelatedProducts. 
FindRelatedProducts: Found application: {0C6604FB-58EC-48B9-8259-5871EFDADEB9} 
MSI (c) (D0:88) [15:46:36:716]: PROPERTY CHANGE: Adding WIX_UPGRADE_DETECTED property. Its value is '{0C6604FB-58EC-48B9-8259-5871EFDADEB9}'. 
MSI (c) (D0:88) [15:46:36:716]: PROPERTY CHANGE: Adding MIGRATE property. Its value is '{0C6604FB-58EC-48B9-8259-5871EFDADEB9}'. 

Los productos existentes se eliminarán independientemente del cheque que se encuentren.

Action start 15:46:41: RemoveExistingProducts. 
RemoveExistingProducts: Application: {0C6604FB-58EC-48B9-8259-5871EFDADEB9} 

En una nota: Esto no eludir una dificultad básica que surge cuando se tiene instaladores de doble propósito: Usuario1 en la máquina podría instalar en su alcance por usuario, y más tarde Usuario2 instala por equipo . El Usuario1 verá ambas instalaciones en su tabla de programas/características, y no sé cuál tiene prioridad. Por lo tanto, considere ir solo con instalaciones por máquina.

+0

Funciona muy bien al revés también =) –

+0

¿Sería posible llevar a cabo estas acciones sin una IU? (No tengo un control para colocar los elementos de publicación), ¿qué podría ser una buena solución? –

7

Lamentablemente, Windows Installer no es compatible. Algunos procesos fuera de su paquete (¿un programador/chainer?) Tendrán que gestionar la actualización de usuario por equipo.

+0

Esto funcionó para un caso especial que tuve una vez, pero no hay garantías - pero útil para la rareza de la solución: http://stackoverflow.com/a/12291807/129130. Me pregunto cómo esto afecta la base de datos de MSI: parece volver a registrar el producto por máquina y anular el registro de una instalación por usuario, pero ¿lo hace para todos los usuarios? No recuerdo. Creo que utilizamos esto como una solución única para sistemas con un solo usuario. –

+0

Esta respuesta es incorrecta. * Puede * verificar ambos ámbitos de instalación para productos existentes. Ver mi respuesta –

1

Se puede utilizar esta técnica para detectar instalación por usuario desde por-máquina a instalar: http://www.mail-archive.com/[email protected]/msg35197.html

+0

+1 corte interesante. Ese hilo de la lista de correo no tiene confirmación de que realmente funcionaría. Ya no me preocupa este problema, así que no puedo probarlo rápidamente. Si alguien puede confirmar que funciona, por favor comente. –

+0

El no funciona. En mi opinión, nunca se ha probado porque ni siquiera compila ... el ID "24INSTALLPERUSER" no es un identificador legal, por ejemplo. Las secuencias 199 y 201 no son correctas. Corregí el truco para que funcionara, comprobé con orca que las dos acciones personalizadas encajarían justo antes y después de FindRelatedProducts, pero en el momento de la instalación, ambas acciones personalizadas se siguen ejecutando después de FindRelatedProducts. Obtiene una "acción de omisión de FindRelatedProducts: ya realizada en el lado del cliente". Lástima, hubiera sido una buena idea ... –

+0

He hecho algo similar y funciona, ver mi respuesta. –

0

Encuentra tanto las instalaciones existentes de perUser como/perMachine. Y obliga a la nueva instalación a una instalación de perMachine (obviamente lógica para hacer que ese condicional se pueda aplicar como lo desee). Esto funciona cuando se ejecuta como una instalación ordinaria y cuando se instala silenciosamente en LocalSystem (actualizaciones silenciosas). Tenga en cuenta que solo puede encontrar una instalación perUser cuando se ejecuta como ese usuario.

Crear una acción personalizada (DLL)

#pragma comment(linker, "/EXPORT:[email protected]") 
extern "C" __declspec(dllexport) UINT __stdcall RunFindRelatedProducts(MSIHANDLE a_hInstall) 
{ 
MsiSetProperty(a_hInstall, "ALLUSERS", "1"); 
MsiDoAction(a_hInstall, "FindRelatedProducts"); 
MsiSetProperty(a_hInstall, "ALLUSERS", ""); 
MsiDoAction(a_hInstall, "FindRelatedProducts"); 
MsiSetProperty(a_hInstall, "ALLUSERS", "1"); 
return ERROR_SUCCESS; 
}//end function 

Entonces "reemplazar" las FindRelatedProducts estándar con la acción personalizada

<InstallUISequence> 
    <FindRelatedProducts>0</FindRelatedProducts> 
    <Custom Action="RunFindRelatedProducts" Before='FindRelatedProducts'>NOT Installed</Custom> 
</InstallUISequence> 
<InstallExecuteSequence> 
    <FindRelatedProducts>0</FindRelatedProducts> 
    <Custom Action="RunFindRelatedProducts" Before='FindRelatedProducts'>NOT Installed</Custom> 
</InstallExecuteSequence> 
Cuestiones relacionadas