2010-02-11 27 views
23

¿Cómo puedo hacer que mi aplicación C# se borre sola (autodestruirse)? Aquí hay dos maneras en que creo que podría funcionar:¿Cómo puedo hacer que mi aplicación .NET se borre sola?

  • Proporcione otro programa que elimine el programa principal. Sin embargo, ¿cómo se borra este programa de eliminación?
  • Cree un proceso para CMD que espere unos segundos y luego borre su archivo. Durante esos pocos segundos, cierra su aplicación.

Ambos métodos parecen ineficaces. Tengo la sensación de que hay alguna bandera incorporada o algo en Windows que permite esas cosas. ¿Cómo debería hacerlo? Además, ¿puedes proporcionar algún código de muestra?

ACTUALIZACIÓN: ¡Gracias por todas sus respuestas! Voy a probarlos, y ver a dónde me lleva eso.

Antes que nada, algunas personas me han preguntado por qué querría que mi aplicación hiciera esto. Aquí está la respuesta: hace unos días, leí las especificaciones del Proyecto Aardvark que Joel Spolsky publicó en su blog, y mencionó que la aplicación del cliente se eliminaría después de la sesión remota. Me pregunto cómo funciona esto, y cómo, si alguna vez necesito hacer esto, puedo lograr tal hazaña.

He aquí un pequeño resumen de lo que se ha sugerido:

  • crear una entrada de registro que indica a Windows para eliminar el archivo en el reinicio
  • lanzamiento CMD con un comando ping que esperar unos segundos y a continuación, elimine el archivo

Ambas, por supuesto, tienen sus desventajas, como se indica en los comentarios.

Sin embargo, ¿funcionaría tal método como se describe a continuación?

Hay dos ejecutables: Program.exe y Cleaner.exe. El primero es el programa en sí, este último es la aplicación que elimina Program.exe y él mismo (si está cargado en la memoria, como estoy a punto de explicar). ¿Es posible que Program.exe (que tiene dependencias) cargue todo Cleaner.exe, que no tiene ninguna dependencia, en la memoria y ejecútelo?

Si esto es posible, ¿se podría empaquetar Cleaner.exe dentro de Program.exe, cargar en la memoria y ejecutar?

+1

¿Realmente necesita eliminar el programa o simplemente deshabilitarlo? Solo quiero ver si entiendo completamente la lógica de negocios porque, por lo general, desactivar completamente algo es más seguro que eliminarlo. –

+0

Sí, desactívelo en lugar de eliminarlo. –

+4

¿Por qué tendrías que hacer esto? Parece que la aplicación no es buena y debes deshacerte de la evidencia. – AGoodDisplayName

Respuesta

19

Hay una API MoveFileEx, que, cuando se les da una bandera MOVEFILE_DELAY_UNTIL_REBOOT, se eliminará el archivo especificado en el siguiente inicio del sistema.

+0

¿Podría un usuario intervenir y evitar que esto ocurra antes del próximo reinicio? – FrustratedWithFormsDesigner

+2

@FWFD: Sí, es bastante fácil. También podrían eliminar las entradas de registro apropiadas (ahí es donde se almacenan las instrucciones para eliminar ese archivo en el próximo reinicio). –

+1

¡Impresionante! ¿Me podría dar algún código de muestra? –

10

Hay un gran CodeProject Article sobre este tema.

Edit: Básicamente se trata de una simple llamada a cmd que eliminará los archivos especificados después de algunos segundos.

Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " + Application.ExecutablePath); 
Application.Exit(); 
+7

Creo que este es el método "espere un segundo y luego elimine" (2ª viñeta de OP). – FrustratedWithFormsDesigner

7

Nunca podrá garantizar que esto funcionará, siempre que requiera una presencia física en la máquina. Por ejemplo:

  • ¿Qué sucede si la aplicación no puede liberar un recurso de manera oportuna mientras intenta eliminarlo? Se produce un error y la aplicación permanece.
  • El comportamiento de una aplicación que inicia otra que luego elimina la primera aplicación es muy sospechoso desde una perspectiva AV. Es probable que active defensas en la máquina de un usuario, lo que puede matar el proceso que está tratando de matar a su aplicación original.
  • Si hace algo así como eliminar un archivo al reiniciar, ¿qué sucede si el usuario mueve el archivo o realiza una copia? Ya no está en el lugar original, y la aplicación permanece.

Si su aplicación requiere este nivel de seguridad, considere hospedarla en un equipo que controle (por ejemplo, proporcionando un servicio web y permitiendo que un cliente stub acceda a él de esa manera).

En una nota algo relacionada, uno también tiene la tentación de especular sobre los motivos de alguien que (1) requiere una presencia física en la máquina de alguien y (2) quiere eliminar la evidencia de que la aplicación existía.

+0

parte del problema de la eliminación al reiniciar se puede solucionar almacenando la aplicación en archivos temporales, casi nadie mira allí apuesto – RCIX

+0

_Teóricamente algo debería ser posible. La memoria RAM es volátil, por lo que si coloca el programa en la memoria, debería poder borrarlo de la HD mientras se ejecuta. Entonces, no importa lo que le ocurra a la máquina, no regresará a menos que tome una instantánea de la memoria.Sin embargo, no sé cómo funcionaría eso en la práctica. – Chris

+0

@Chris: no, porque no puede garantizar que la memoria proporcionada por un sistema operativo esté destinada a un almacenamiento volátil. (De hecho, si esto no fuera cierto, se vencería todo el punto de cosas como la memoria virtual y ReadyBoost.) –

1

También hay FileOptions.DeleteOnClose, pero eso requiere que el archivo esté abierto para la escritura. Usted puede ser capaz de hacerlo con una secuencia como esto (no probado):

  • Programa lanza como Original.exe, y detecta (de su propio nombre) que necesita para activar la función de auto-destrucción.
  • Original.exe crea un nuevo archivo Temp.exe con FileOptions.DeleteOnClose y copia su propio contenido en ella, pero no cierra todavía
  • Original.exe abre una segunda, de sólo lectura a manejar Temp.exe y cierra el primer mango de escritura. El controlador de solo lectura puede coexistir con un controlador de ejecución, mientras mantiene el archivo abierto para retrasar la eliminación automática.
  • Original.exe lanza Temp.exe. Temp.exe detecta que se ha iniciado desde el directorio temporal y omite la secuencia de autodestrucción y continúa el funcionamiento normal.
  • Original.exe salidas (tomando su lectura sólo manejan a Temp.exe con él.)
  • Temp.exe continúa funcionando. Cuando sale, el archivo Temp.exe ya no estará en uso, por lo que se eliminará automáticamente.

Edición # 2: En realidad no creo que esto es posible, porque se basa en el kernel de abrir el archivo con la bandera FILE_SHARE_DELETE, lo cual es poco probable.

+0

Suena posible, ¿hay alguna manera de hacer algo de interoperabilidad y forzarlo a abrir de esa manera? – RCIX

0

Sé que el reflector se elimina automáticamente si utiliza una versión anterior y elige no actualizar. Puede intentar averiguar qué hace. Comenzaría con FileMon y vería si genera procesos para lograr esto.

+0

Esa es una buena idea. Le daré un vistazo. –

4

Corrección de la respuesta de @Bobby, en caso de que las personas lo encuentren útil: es necesario citar la ruta ejecutable. Además, a continuación, se establece la ventana cmd.exe para que se oculte (de lo contrario, parpadea como una ventana de consola negra) y se convierte para ejecutar sin depender del ensamblado System.Windows.Forms (la clase Application).

 
var exepath = Assembly.GetEntryAssembly().Location;    
var info = new ProcessStartInfo("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del \"" + exepath + "\""); 
info.WindowStyle = ProcessWindowStyle.Hidden; 
Process.Start(info).Dispose(); 
Environment.Exit(0); 
1

ordenado por NJ C# los otros códigos no funcionan por lo que su sencilla si u crear el archivo de baño que se repite a Del aplicación y el archivo por lotes en sí u puede utilizar takkill comando para matar el proceso si U no quieren usar método application.close

 `string delname = "test.cmd"; 
     string fileurl = Application.ExecutablePath; 
     System.IO.StreamWriter file = new System.IO.StreamWriter(delname); 
     file.WriteLine(":Repeat"); 
     file.WriteLine("del \"" + fileurl + "\""); 
     file.WriteLine("if exist \"" + fileurl + "\" goto Repeat"); 
     file.WriteLine("del \"" + delname + "\""); 
     file.Close(); 
     ProcessStartInfo startInfo = new ProcessStartInfo(); 
     startInfo.CreateNoWindow = true; 
     startInfo.UseShellExecute = false; 
     startInfo.FileName = delname; 
     startInfo.WindowStyle = ProcessWindowStyle.Hidden; 
     Process.Start(startInfo);` 

` Th3 3e3 uno no es uno ov partes 3d I5 ~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~

1

Piense CMD

int sectosleep = 5000; 
string exename = "yourexe.exe"; 
string location = @"c:\yourexe.exe" 
Process.Start("cmd.exe", "/C taskkill /f /im " + exename + " & ping 1.1.1.1 -n 1 -w " + sectosleep + " > Nul & Del /F /Q \"" + location + "\""); 

;>

0

Desde mi solicitud (un servicio de Windows) es instalado a través del instalador de Windows, me auto-eliminar el uso de este:

Dim uninstall_params As String = "/x {MY-PRODUCTS-GUID} /qn /norestart REBOOT=ReallySuppress" 
proc.StartInfo = New ProcessStartInfo("msiexec.exe", uninstall_params) 
proc.Start() 
Environment.Exit(-1) 

lo sentimos - es en VB, pero debería ser fácilmente convertible en C#.

0

Funciona en Windows 7 & 8, ** ASEGÚRESE de ejecutar su aplicación con privilegios de administrador o se producirá un error.

Este código existe en otro lugar, así que no puedo tomar todo el crédito. Descubrí que lo hice funcionar agregando "Application.Exit();"

static void autodelete() 
{ 
    string batchCommands = string.Empty; 
    string exeFileName = Assembly.GetExecutingAssembly().CodeBase.Replace("file:///", string.Empty).Replace("/", "\\"); 

    batchCommands += "@ECHO OFF\n";       // Do not show any output 
    batchCommands += "ping 127.0.0.1 > nul\n";    // Wait approximately 4 seconds (so that the process is already terminated) 
    batchCommands += "echo j | del /F ";     // Delete the executeable 
    batchCommands += exeFileName + "\n"; 
    batchCommands += "echo j | del deleteMyProgram.bat"; // Delete this bat file 

    File.WriteAllText("deleteMyProgram.bat", batchCommands); 

    Process.Start("deleteMyProgram.bat"); 
    Application.Exit(); 
} 
Cuestiones relacionadas