Pregunta

Quiero actualizar mi EXE desde el servidor remoto.Entonces, cuando el botón hizo clic en mi aplicación WPF, descargará el control remoto y también un archivo TXT remoto y reemplazará las actuales en la misma carpeta que se ejecuta EXE.Por lo tanto, sobrescribirá el archivo actual de TXT y EXE mientras que mi EXE está funcionando.¿Cómo puedo lograr esto?

El host remoto es URL como www.mydomain.com/MyAPP.exe

Aplicación WPF, C # 4.0

¿Fue útil?

Solución

La forma en que resolvimos este problema fue crear un EXE de shell que, como se instaló y desplegado inicialmente a las máquinas cliente.

El programa ejecutable "real" se almacena en un subdirectorio de esta aplicación inicial.Cuando se inicia la aplicación Shell, después de que haya descargado e instalado cualquier actualización de la aplicación real, se inicia el ejecutable de la aplicación real en un AppDomain separado.

Aquí está el núcleo del lanzamiento de la aplicación "real" desde la aplicación Shell:

        System.AppDomainSetup oSetup = new System.AppDomainSetup();
        string sApplicationFile = null;

        // Use this to ensure that if the application is running when the user performs the update, that we don't run into file locking issues.
        oSetup.ShadowCopyFiles = "true";
        oSetup.ApplicationName = sAppName;

        // Generate the name of the DLL we are going to launch
        sApplicationFile = System.IO.Path.Combine(sApplicationDirectory, sAppName + ".exe");

        oSetup.ApplicationBase = sApplicationDirectory;
        oSetup.ConfigurationFile = sApplicationFile + ".config";
        oSetup.LoaderOptimization = LoaderOptimization.MultiDomain;

        // Launch the application
        System.AppDomain oAppDomain = AppDomain.CreateDomain(sAppName, AppDomain.CurrentDomain.Evidence, oSetup);
        oAppDomain.SetData("App", sAppName);
        oAppDomain.SetData("User", sUserName);
        oAppDomain.SetData("Pwd", sUserPassword);

        oAppDomain.ExecuteAssembly(sApplicationFile);

        // When the launched application closes, close this application as well
        Application.Exit();

Tenga en cuenta que en nuestra versión, la aplicación Shell recopila el nombre de usuario y la contraseña del usuario para acceder correctamente al sitio web de actualización.Estos datos se pasan luego a la aplicación "real" a través del método SetData en el AppDomain.

Otros consejos

La solución depende de su caso particular. Pero no hay una solución directa, ya que no puede actualizar los ensamblajes mientras se cargan en la memoria y se están utilizando. Puedo proponer 2 soluciones: usando Copia de sombra y usando algún tipo de ayudante ejecutable. He usado ambos.

Shadow Copiando.

La forma obvia es hacer que su ejecutable principal sea copiado, reemplácelo mientras su aplicación se está ejecutando y luego reinicie la aplicación. Pero usted no puede hacer que su dominio de aplicación predeterminado sea copiado, solo los dominios de la aplicación secundaria pueden ser. Pero aún puede mover todo su código a otra asamblea (digamos, mainapplib.dll) y reescriba su ejecutable de la aplicación principal (mainapp.exe) para que contenga solo "código de cargador". Este código de cargador tiene que crear otro dominio de la aplicación, configúrelo para ser copiado de la sombra y luego ejecutar la lógica del programa en el dominio de la aplicación secundaria. Tenga cuidado de no tener ninguna referencia directa de su dominio principal de la aplicación en mainapplib.dll porque entonces este conjunto se cargará en su dominio principal de la aplicación que no está copiado en la sombra y el archivo de ensamblaje se bloqueará. En la mayoría de los casos, puede ir con appdomain.executeassembly () Métodos.

ayudante ejecutable

La idea es usar algún tipo de acabado de actualización . Su aplicación principal permanece sin cambios, solo agrega una pequeña cantidad de código, por lo que su aplicación descargará la actualización, colóquela en una carpeta temporal, y luego su aplicación principal inicie Actualice Finisher ( en proceso separado ) y salidas. Actualizar el finalizador espera hasta que su aplicación se cierre y luego copie los archivos nuevos de la carpeta temporal a su carpeta de aplicaciones que reemplazan todos los archivos. Actualizar Finalisher No puede reemplazar su propio ejecutable, pero se puede hacer por la aplicación principal antes de que inicie el finalizador de actualización. Después de copiar los archivos de actualización, la finalizador ejecuta su solicitud.

P.s. personalmente prefiero la solución anterior porque implica algún tipo de magia vudú usando dominios de la aplicación, reflexión, ensamblajes E.T.C. Y se puede evolucionar en el uso de complementos si necesita (por ejemplo, a través de MEF Framework ). Pero este último es más fácil de entender, especialmente si nunca ha trabajado con dominios de aplicación y conjuntos manuales, es bastante sencillo.

probablemente podría usar Clickonce (basado en su comentario por encima de esoEstaría preparado para que otra asamblea obtenga el EXE ... como el otro póster mencionado, no puede reemplazar un ensamblaje en funcionamiento).Puede configurarlo para verificar en varias Times (por ejemplo, Startup) para nuevas versiones y las descarga automáticamente.Es una solución muy robusta y puede hacer mucho con las asambleas de despliegue.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top