plataforma - update mono
Ejecutando y luego borrando una DLL en c# (4)
Desenvolver cargará el ensamblaje del tipo del objeto en el dominio de aplicación que lo llama. Una forma de evitar esto es crear un tipo en su ensamblado "base" que llame a command.run y luego cargarlo en su nuevo appdomain. De esta forma, nunca tendrá que llamar desenvolver a un objeto de un tipo en un ensamblaje diferente, y puede eliminar el ensamblaje en el disco.
Estoy creando una aplicación de actualización automática donde tengo la mayoría del código en una DLL separada. Es línea de comando y eventualmente se ejecutará en Mono. Solo estoy tratando de hacer que este código funcione en C # en ventanas en la línea de comando.
¿Cómo puedo crear la aplicación ac # que puedo eliminar un dll de soporte mientras se está ejecutando?
AppDomain domain = AppDomain.CreateDomain("MyDomain");
ObjectHandle instance = domain.CreateInstance( "VersionUpdater.Core", "VersionUpdater.Core.VersionInfo");
object unwrap = instance.Unwrap();
Console.WriteLine(((ICommand)unwrap).Run());
AppDomain.Unload(domain);
Console.ReadLine();
en la ReadLine, VersionUpdater.Core.dll todavía está bloqueado desde la eliminación
La interfaz de ICommand está en VersionUpdater.Common.dll a la que hacen referencia tanto la aplicación Commandline como VersionUpdater.Core.dll
La única forma en que alguna vez he manejado algo similar es tener el DLL en un AppDomain separado para el ensamblado que está tratando de eliminarlo. Descargo el otro AppDomain y luego elimino el DLL del disco.
Si estás buscando una manera de realizar la actualización, iría por un exe de stub que genere el dominio de aplicación real. Luego, cuando ese stub exe detecta que se va a aplicar una actualización, abandona el otro AppDomain y luego actualiza la magia.
EDITAR: el actualizador no puede compartir archivos DLL con lo que está actualizando; de lo contrario, bloqueará esos archivos DLL y, por lo tanto, evitará que se eliminen. Sospecho que es por eso que todavía obtienes una excepción. El actualizador debe ser independiente y no depender de nada que el otro AppDomain use, y viceversa.
Cuando construí una aplicación de actualización automática, utilicé la idea del talón, pero el talón fue la aplicación en sí.
La aplicación comenzaría, busca las actualizaciones. Si encuentra una actualización, descargará una copia de la nueva aplicación para el almacenamiento temporal y luego la iniciará (System.Diagnostics.Process.Start ()) utilizando una opción de línea de comando que dice "usted está siendo actualizado". Entonces el exe original sale.
El exe generado se inicia, ve que es una actualización y se copia al directorio de la aplicación original. A continuación, inicia la aplicación desde esa nueva ubicación. Entonces el exe engendrado termina.
Se inicia el nuevo archivo ejecutable de la ubicación de instalación de la aplicación original: ve el archivo temporal y lo elimina. Luego reanuda la ejecución normal.
Siempre puede usar MOVEFILE_DELAY_UNTIL_REBOOT
para eliminar al reiniciar. Esta es probablemente la forma menos peligrosa para todo este tipo de cosas, por Hackey usualmente veo cosas como; cargar nuevas DLL o inyectar a explorer.exe incluso parcheando un archivo DLL del sistema para cargarlo en otro proceso, etc.
MoveFileEx desde MSDN ;
lpNewFileName [in, opcional ] El nuevo nombre del archivo o directorio en la computadora local.
Al mover un archivo, el destino puede estar en un sistema de archivos o volumen diferente. Si el destino está en otra unidad, debe establecer el indicador MOVEFILE_COPY_ALLOWED en dwFlags.
Al mover un directorio, el destino debe estar en la misma unidad.
Si dwFlags especifica
MOVEFILE_DELAY_UNTIL_REBOOT
y lpNewFileName es NULL , MoveFileEx registra el archivo lpExistingFileName que se eliminará cuando se reinicie el sistema. Si lpExistingFileName se refiere a un directorio, el sistema elimina el directorio al reiniciarlo solo si el directorio está vacío.