2012-02-06 10 views
23

I asked this question en un contexto de diseño más general antes. Ahora, me gustaría hablar sobre los detalles.¿Cómo puede reemplazarse un binario en C++?

Imagine que tengo app.exe ejecutándose. Descarga update.exe en la misma carpeta. ¿Cómo podría app.exe copiar update.exe sobre los contenidos de app.exe? Estoy preguntando específicamente en un contexto de C++. ¿Necesito algún tipo de aplicación de mediación tercero? ¿Debo preocuparme por el bloqueo de archivos? ¿Cuál es el enfoque más robusto para una actualización binaria en sí (salvo que el personal de TI desagradable tenga permisos de archivos extremos)? Idealmente, me gustaría ver soluciones portátiles (Linux + OSX), pero Windows es el objetivo principal.

+0

Por lo que sé, Windows no le permitirá sobrescribir un EXE mientras se ejecuta el programa. Esta es una de las cosas más molestas en Windows, imo. – unwind

+1

Como te dije en esa otra pregunta, no puedes sobrescribir un exe que se está ejecutando. Incluso di instrucciones paso a paso sobre cómo hacer todo este proceso. –

+0

@MooingDuck ¡Lo sé! Todavía estoy haciendo referencia a su respuesta como un diseño de alto nivel. Simplemente estoy reduciendo el alcance de esta pregunta en particular. Ya estoy bastante satisfecho con las respuestas. – TheBuzzSaw

Respuesta

35
  1. Mover/Cambiar el nombre de su funcionamiento app.exe-app_old.exe
  2. Mover/cambiar el nombre de descargarse update.exe-app.exe
  3. Con el próximo inicio de su aplicación se usará la actualización

Renombrar una ejecución, es decir, dll/exe bloqueado no es un problema bajo Windows.

+7

¡no sabía que podía cambiar el nombre de un ejecutable en ejecución! –

+0

Esto funcionó bastante bien para mí, soluciona el problema del huevo y la gallina con mi actualizador. – Boccobrock

9

Es una característica del sistema operativo, no una de C++.
¿En qué SO estás?

En Windows ver la función MoveFileEx(), en Linux simplemente sobrescribir la aplicación en ejecución (Replacing a running executable in linux)

+0

+1 para el enlace al otro tema. ¡La solución de Linux es increíble! – Nawaz

7

En Linux es posible eliminar el ejecutable de un programa en ejecución, por lo tanto:

  • descarga app.exe~
  • eliminar corriendo app.exe
  • cambiar el nombre app.exe~ a app.exe

En Windows se no es posible eliminar el ejecutable de un programa en ejecución, pero es posible cambiarle el nombre:

  • descarga app.exe~
  • renombrar corriendo app.exe a app.exe.old
  • app.exe~ renombrar a app.exe
  • al reiniciar eliminar app.exe.old
2

En Windows, al menos, una aplicación ejecutándose está bloqueando su propio archivo .exe y todos los archivos .dll enlazados estáticamente. Esto evita que una aplicación se actualice directamente, a clientes potenciales si desea evitar un reinicio (si la reinicialización es correcta, la aplicación puede pasar en el indicador MOVEFILE_DELAY_UNTIL_REBOOT a MoveFileEx y puede 'sobrescribir' su propio .exe, como se retrasa de todos modos). Esta es la razón por la cual las aplicaciones típicamente no comprueban las actualizaciones en su propio .exe, sino que comienzan una revisión que busca actualizaciones y luego lanza la aplicación 'real'. De hecho, el 'shim' incluso puede ser hecho por el propio sistema operativo, en virtud de un archivo de manifiesto configurado correctamente. La aplicación construida de Visual Studio obtiene esto como una herramienta empaquetada del asistente prefabricado, consulte ClickOnce Deployment for Visual C++ Applications.

La aplicación típica de Linux no se actualiza debido a los muchos muchos muchos sabores del sistema operativo. La mayoría de las aplicaciones se distribuyen como fuente, se ejecutan a través de una versión de auto-infierno para autoconfigurarse y compilarse, y luego se instalan a través del make install (todas estas se pueden automatizar detrás de un paquete). Incluso las aplicaciones que se distribuyen como binarios para un sabor específico de Linux no se copian, sino que instalan la nueva versión una al lado de la otra y luego actualizan un symbolic link para 'activar' la nueva versión (de nuevo, una administración de paquetes) el software puede ocultar esto).

Las aplicaciones de OS X caen en el cubo de Linux si tienen el sabor de Posix, o caen en el cubo de la aplicación Mac AppStore que maneja las actualizaciones por usted.

Me gustaría que la actualización de su propia auto-actualización nunca alcance la sofisticación de ninguna de estas tecnologías (ClickOnce, RPM, AppStore) y ofrezca al usuario el comportamiento esperado ante descubrimiento, actualización y desinstalación. Me gustaría ir con la corriente y usar estas tecnologías en sus respectivas plataformas.

+0

¿Qué pasa con las aplicaciones que se ejecutan continuamente? En mi caso, la aplicación se ejecuta todo el tiempo y busca activamente las actualizaciones (además de realizar sus diversas tareas). ¿Todavía recomendaría usar esas mismas herramientas de actualización? – TheBuzzSaw

+0

¿Es el usuario de la aplicación interactivo o daemon/servicio? Las aplicaciones interactivas del usuario como ClickOnce pueden notificar al usuario. el tipo daemon/servicio depende del entorno: en un entorno empresarial, los administradores los actualizan, que son muy reacios a las aplicaciones para descargar automáticamente y ejecutar nuevos bits (no comprobados, y lo que es más importante, potencialmente comprometidos). A un daemon/servicio de consumidor le sería más fácil vender los beneficios de la actualización automática. –

+0

Lo clasificaría como daemon/servicio. Fundamentalmente, está ahí para extraer datos (según lo permita el usuario). Sin embargo, aparecen errores.Un ejemplo al azar podría ser que los nombres de las personas están retrocediendo. Quiero ser capaz de sacar una pequeña corrección de errores sin todos los lujos de una instalación de software completa. – TheBuzzSaw

2

Solo una idea para solucionar el problema del "reinicio". ¿Qué hay de hacer un programa que no necesita ser actualizado? Simplemente impleméntelo en una estructura de complementos, por lo que solo se trata de un host de actualización que a su vez carga un archivo .dll con toda la funcionalidad que su programa necesita y llama a la función principal allí. Cuando detecta una actualización (posiblemente en un hilo separado), le dice al manejador dll que cierre, reemplaza el archivo y carga el nuevo. De esta forma, la aplicación seguirá ejecutándose mientras se actualiza (solo se vuelve a cargar el archivo dll, pero la aplicación sigue ejecutándose).

0

Utilice un 3er ejecutable de actualización como muchas otras aplicaciones.

  • Descargue la nueva versión.
  • Programe su actualizador para reemplazar la aplicación con la nueva versión.
  • Cerrar la aplicación principal.
  • Updater se ejecuta y hace el trabajo.
  • Updater ejecuta la nueva versión de su aplicación.
  • Se cierra el actualizador.