2011-10-23 20 views
5

Estoy usando C#, .net 4, WIX 3.5, Windows Vista. He hecho mi aplicación compatible con RestartManager al invocar el método RegisterApplicationRestart y al manejar los mensajes de la ventana WM_QUERYENDSESSION y WM_ENDSESSION (devuelvo new IntPtr(1);).RestartManager no puede reiniciar la aplicación durante la actualización

Si trato de actualizar mi aplicación manualmente, entonces todo funciona como debería:

  1. Iniciar aplicación;
  2. Ejecuta el archivo msi que contiene la nueva versión de la aplicación;
  3. Durante la instalación/actualización, se me pide que cierre la aplicación en ejecución;
  4. Al continuar, la aplicación en ejecución se cierra, la instalación finaliza y la aplicación se reinicia;

Si trato de actualizar mi aplicación desde la propia aplicación, entonces a tener problemas:

1) Iniciar aplicación;
2) Descargue el nuevo archivo msi;
3) msi lanzamiento con:

using (System.Diagnostics.Process p = new System.Diagnostics.Process()) 
    { 
     p.StartInfo.UseShellExecute = false; 
     p.StartInfo.FileName = "msiexec"; 
     p.StartInfo.Arguments = "/i \"" + downloadPath + "\" /passive"; 
     p.StartInfo.UserName = "Administrator"; 
     p.StartInfo.Password = securePassword; 
     p.Start(); 
    } 

4) Debido a que estoy usando el modo pasivo, la aplicación se cierra de forma automática;
5) Después de la instalación, mi aplicación no se reinicia y en el Visor de eventos tengo un
Evento 10007 - La aplicación o servicio 'MyApp' no se pudo reiniciar.

que he intentado:

  1. desea utilizar el modo pasivo para msiexec;
  2. Ejecute msiexec mediante cmd.exe (cmd.exe/C "msiexec/i ....") - con la esperanza de que el lanzamiento de msiexec desde otro proceso solucione el problema;
  3. Espere a más de 60 segundos antes de lanzar la actualización de MSI (no debería ser relevante en mi escenario, pero la documentación de MSDN tiene algo al respecto ...)

Pero ninguno de los anteriores ha trabajado (siempre el mismo resultado).

Tener que iniciar la instalación con permisos elevados puede tener algo que ver con el problema, porque durante la actualización manual recibo una advertencia en el Visor de sucesos - Aplicación MyApp (pid 3220) no se puede reiniciar: la aplicación SID no coincida Conductor SID.
A pesar de esto, reiniciar la aplicación todavía funciona. Al buscar la advertencia, no se obtienen resultados buenos/específicos, solo que esta advertencia probablemente se deba a que se ejecuta el msi en un aviso elevado.

¿Cómo soluciono (o soluciono) este problema, para poder actualizar mi aplicación desde la propia aplicación y reiniciar luego mi aplicación?

Editar - pruebas adicionales:

  1. No parece ser una necesidad de responder a los mensajes y WM_QUERYENDSESSION WM_ENDSESSION, porque el reinicio de aplicaciones durante una actualización manual funciona sin ellos, por lo que se puede descartar ellos afuera;
  2. Si no proporciono credenciales de administrador para la actualización iniciada por la aplicación y en su lugar las escribo durante la actualización, entonces el reinicio de la aplicación funciona;
  3. Si ejecuto un símbolo del sistema elevado e inicio una actualización de la aplicación desde allí (manualmente), entonces el reinicio de la aplicación todavía funciona;
  4. Para que la actualización de la aplicación funcione bajo las cuentas de usuario estándar (hasta ahora he probado bajo una cuenta de administrador con UAC), entonces también tengo que configurar p.StartInfo.LoadUserProfile = true;. De lo contrario, no pasa nada. (el reinicio de la aplicación todavía no funciona);
  5. Intenté todos los otros parámetros StartInfo del proceso que pude establecer - WorkingDirectory, Redirect, Verb
    (= "runas") - sin cambios en los resultados;
  6. Instalé Vista SP2 en la máquina virtual en la que he estado probando (hasta ahora ejecuté SP1), pero no cambio;
  7. Realicé una actualización de la aplicación "automática" con un registro detallado. Al final, apareció un mensaje de error: RESTART MANAGER: error al reiniciar las aplicaciones. Error: 352. Ese código de error es muy genérico (http://msdn.microsoft.com/cs-cz/library/aa373665), para obtener información más detallada, tendría que escribir mi propio instalador que llamaría RmGetList después del error, entonces podría obtener más detalles (aunque esto es algo que no estoy dispuesto que hacer);

Edición 2 - msi archivo de registro:
http://mommi.planet.ee/muu/log.txt

+0

¿Ha intentado utilizar la API de MSI directamente [ 'MsiInstallProduct'] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa370315.aspx)? Lamentablemente, no conozco su contraparte en el entorno .Net. –

+0

No he probado esa API de MSI antes, pero lo probé.Dos problemas: 1) Que la API no es compatible con RestartManager (me pide que reinicie la computadora); 2) No parece haber una manera de pasar privilegios de administrador (una necesidad en mi escenario). – Marko

+0

podría proporcionar un archivo de registro de la instalación de msi. puede sacarlo de msiexec agregando el parámetro "/ l * v% temp% \ mylog.log". eso podría darnos una pista sobre el problema – weberik

Respuesta

0

Suponiendo que el proceso manual de hecho funciona sin ningún problema parece ser que su necesidad de privilegios de administrador en combinación con la "actualización de sí mismo" conduce a estos problemas. Veo las siguientes opciones:

  • crear un archivo por lotes para ejecutar la actualización
    Cuando desea actualizar llamar a este archivo por lotes (con privilegios elevados), hacer que la aplicación cerrarse ... el archivo de lote debe espere unos segundos, luego verifique si la aplicación todavía se está ejecutando (y ciérrela por si acaso) y luego ejecute la línea de comando que necesita para ejecutar msiexec - no reinicie la aplicación desde msiexec pero después de una ejecución exitosa de msiexec desde el archivo por lotes .

  • crear un archivo por lotes que siempre se utiliza para iniciar la aplicación
    Cuando llegue el momento de actualizar, simplemente termine la aplicación. El archivo por lotes comprueba si hay una actualización disponible y la aplica, iniciando la aplicación después de una actualización exitosa O la aplicación establece alguna variable de entorno que el resto del archivo por lotes procesa en consecuencia.

+1

Creo que tiene usted razón al tener que crear un archivo por lotes separado o ejecutable para realizar una actualización en mi escenario. Creo que esto se debe a alguna limitación/error en Windows. Sin embargo, una cosa que agregaría es que, para reiniciar la aplicación con los privilegios de usuario actuales (no administrador), entonces necesitaría dos archivos. La aplicación principal llamará a la primera que llamará a la segunda con derechos de administrador (que llama a msiexec), luego la primera iniciará la aplicación principal. Debido a que se llama al primer ejecutable con los privilegios de usuario actuales, la aplicación también se inicia con los derechos de usuario actuales ... – Marko

Cuestiones relacionadas