2009-08-20 6 views
27

¿Es posible hacer que una aplicación en C# que será capaz de borrarse a sí mismo de alguna condición.Auto aplicación deletable en C# en un ejecutable

Tengo que escribir un actualizador para mi aplicación, pero no quiero que el ejecutable que se queda después del proceso de actualización.

Hay un funcionario .Net OneClick pero debido a algunas incompatibilidades con mi servidor HTTP y algunos problemas de OneClick sí estoy obligado a hacer uno yo mismo.

George.

[EDIT] En más detalles:

tengo: aplicación ejecutable que descarga el programa de actualización ("parche", pero no exactamente) este "parche" actualizaciones de la aplicación ejecutable en sí.

aplicación se ejecuta como folowed:

Application: Start -> Check Version -> Download new Updater -> Start Updater -> exit; 
Updater: Start -> do it's work -> start Application Executable -> self delete (this is where I get stuck); 
+1

¿Ha preguntado acerca de los problemas con OneClick? Puede ser que resolvería la pregunta. – Christian13467

+0

No es el OneClick. Actualicé la pregunta y agregué la rutina de aplicación para mayor precisión. – George

Respuesta

30

Si utiliza Process.Start puede pasar el parámetro Del y la ruta a la aplicación que desea eliminar.

ProcessStartInfo Info=new ProcessStartInfo(); 
Info.Arguments="/C choice /C Y /N /D Y /T 3 & Del "+ 
       Application.ExecutablePath; 
Info.WindowStyle=ProcessWindowStyle.Hidden; 
Info.CreateNoWindow=true; 
Info.FileName="cmd.exe"; 
Process.Start(Info); 

fragmento de código tomado de this article

+0

Gracias por el artículo. No sé por qué no pude encontrarlo: S – George

+2

¿Qué pasa si la aplicación no se cierra en 3 segundos? –

+0

@AlexZhukovskiy el tiempo de espera en el ejemplo no dicta cuánto tiempo debe esperar el sistema antes de intentar eliminar la aplicación, el tiempo de espera solo desencadena un valor predeterminado para forzar el cierre de la aplicación. Simplemente está indicando a la línea de comando que después de que exista el proceso, ejecute el [del] (https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/del.mspx? mfr = true) comando. – James

0

MHH así que vamos a ver si lo entiendo. ¿Tienes alguna application.exe y tu actualizador de la aplicación updater.exe?

Así que cuando se inicia el aplicación.exe comprueba algún servidor web para una versión más reciente y luego comienza updater.exe. ¿Y desea que updater.exe se elimine luego de que haya terminado de actualizarse? ¿O desea eliminar el parche descargado (o similar)? Por favor, sea un poco más preciso.

considerar que cuando está eliminando updater.exe debe volver a crear para el próximo proceso de actualización.

+0

Agregué la rutina de aplicación para mayor precisión. – George

0

su segunda línea puede ser

Updater: Star -> do it's work -> start Application Executable -> Updater Exits -> Application deletes your Updater.exe 
+0

Pensé en eso, pero necesito que el actualizador se elimine solo. – George

+0

Interesante. Usted está luchando con la solución que no parece funcionar. ¿Cuál es el problema? ¿POR QUÉ quiere que el actualizador se elimine solo y por qué no la aplicación? –

2

No podría simplemente eliminar el programa de actualización desde la aplicación? es decir:

Aplicación: Inicio -> [Eliminar el actualizador anterior si está presente] -> Comprobar versión -> Descargar nuevo actualizador -> Iniciar el actualizador -> salir;

actualizador: Inicio -> Ejecutar actualización -> Iniciar la aplicación -> salida;

Aplicación: Inicio -> [Eliminar vieja actualizador si está presente] -> ...

5

Es complicado sin introducir otro proceso (que habías entonces quiere eliminar, así, sin duda). En su caso, que ya tiene 2 procesos - updater.exe y aplicación.exe. Probablemente solo tenga la aplicación delete updater.exe cuando se genere a partir de allí: podría usar una simple línea de comando arg o una llamada IPC desde updater.exe a application.exe para desencadenarlo. Eso no es exactamente un EXE de eliminación automática, pero cumple los requisitos, creo.

Para el tratamiento completo, y otras opciones, debe leer the definitive treatment of self deleting EXEs. Ejemplos de código están en C (o ASM), pero deberían ser p/invocable.

probablemente me trato con CreateFileFILE_FLAG_DELETE_ON_CLOSE para updater.exe con algo como (pseudo código):

var h = CreateFile(
      "updater.exe", 
      GENERIC_READ | GENERIC_WRITE, 
      FILE_SHARE_DELETE, 
      NULL, 
      CREATE_NEW, 
      FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE 
     ); 

byte[] updaterBytes = GetUpdaterBytesFromWeb(); 
File.WriteAllBytes("updater.exe", updaterBytes); 

Process.Start("updater.exe"); 

Una vez aplicación.exe salidas, updater.exe tiene un identificador de archivo de 1. Cuando actualizador. exe sale, cae a 0 y debe ser eliminado.

+3

Lamentablemente, eso no parece funcionar porque el proceso debería iniciarse con 'FILE_SHARE_DELETE' - which Process.Start no funciona. Luego no puede iniciar el proceso porque el archivo aún está abierto (y no se puede cerrar porque eso lo eliminaría). – urbanhusky

8

le sugiero que utilice un archivo por lotes como de arranque y tienen que borrarse a sí mismo y el exe después

public static class Updater 
{ 
    public static void Main() 
    { 
     string path = @"updater.bat"; 

     if (!File.Exists(path)) 
     { 
      // Create a file to write to. 
      using (StreamWriter sw = File.CreateText(path)) 
      { 
       sw.WriteLine("updater.exe"); 
       sw.WriteLine("delete updater.exe /y"); 
       sw.WriteLine("delete updater.bat /y"); 
      } 

      System.Process.Start(path); 
     } 
     else 
     { 
      RunUpdateProcess(); 
     } 
    } 

    private void RunUpdateProcess() 
    { 
     ..... 
    } 
} 
+0

Simplemente no "eliminar .../y", pero "del .../Q" – Boogier

-1
public void uninstall() { 
    string app_name = Application.StartupPath + "\\" + Application.ProductName + ".exe"; 
    string bat_name = app_name + ".bat"; 

    string bat = "@echo off\n" 
     + ":loop\n" 
     + "del \"" + app_name + "\"\n" 
     + "if Exist \"" + app_name + "\" GOTO loop\n" 
     + "del %0"; 

    StreamWriter file = new StreamWriter(bat_name); 
    file.Write(bat); 
    file.Close(); 

    Process bat_call = new Process(); 
    bat_call.StartInfo.FileName = bat_name; 
    bat_call.StartInfo.WindowStyle = ProcessWindowStyle.Hidden; 
    bat_call.StartInfo.UseShellExecute = true; 
    bat_call.Start(); 

    Application.Exit(); 
} 

auto eliminar mediante un archivo ".bat" ejecutable externo para aplicaciones de Windows Forms.

+0

Parece bastante similar a un enfoque de archivo por lotes anterior, pero puede iterarse infinitamente en condiciones de error, lo que no parece prudente. –

Cuestiones relacionadas