11

I built a basic Windows Form app. I want to make it so that my program deletes itself after a date of my choosing.

Specifically, when someone clicks on the .exe to run it, and if it's after a certain date, the .exe is deleted. Is this possible? If yes, how do I do this?

I think my code would look something like this:

DateTime expiration = new DateTime(2013, 10, 31) //Oct. 31, 2013

If (DateTime.Today > expiration) 
{
    //command to self-delete
}
else  
{
    //proceed normally
}
MrPatterns
  • 4,184
  • 27
  • 65
  • 85
  • 2
    Shouldn't it be up to the user when to delete or uninstall something? –  Oct 30 '13 at 16:54
  • just trigger another process to delete it - which runs after your main program has exited – Weyland Yutani Oct 30 '13 at 16:55
  • http://stackoverflow.com/questions/1305428/self-deletable-application-in-c-sharp-in-one-executable – devshorts Oct 30 '13 at 16:55
  • 1
    @Amy No, I want my little program to self-destruct like in the movies! Or, at a minimum, thrown into the Recycle Bin. – MrPatterns Oct 30 '13 at 16:56
  • Launch another process to delete it. User opens your app, it sees it is past a certain date, it launches something else, quits, the "something else" deletes the app. It can be something as simple as a batch file! – Arran Oct 30 '13 at 16:59
  • can you not just disable the program at a certain date? why delete it? The user will be able to re-add it anyway. – Weyland Yutani Oct 30 '13 at 17:00
  • I love Undelete.exe. Am I a "locksmith"? – Kris Vandermotten Oct 30 '13 at 17:04
  • 1
    @Kris To the users I'm dealing with you are an off-the-charts GENIUS! – MrPatterns Oct 30 '13 at 17:05
  • @phan LOL. Seriously, forget about all these tricks. Just tell them the trial expired in a nice message box and quit. If you have time to spend, spend it writing code that makes your user want to buy the app. Or write a Windows Store app, the store has many features that help you deal with situations like this. – Kris Vandermotten Oct 30 '13 at 17:09
  • @Kris Your underlying assumption is faulty as my code is simply not for sale! – MrPatterns Oct 30 '13 at 18:18
  • My console app is deleting itself. Started a new visual studio console app and tried to run it, got an access denied error. When I looked in the output directory, I could see the file was created when I build it. When I double click it in explorer to run it, it deletes itself. That explains the access denied error when trying to debug it, because the app deletes itself immediately upon running. If I copy it out of the directory onto my desktop and run it, it deletes itself. 100% Visual Studio magic. So yes, it's certainly possible. – Triynko Aug 09 '18 at 18:21

6 Answers6

23

This works, runs a commandline operation to delete yourself.

Process.Start( new ProcessStartInfo()
{
    Arguments = "/C choice /C Y /N /D Y /T 3 & Del \"" + Application.ExecutablePath +"\"",
    WindowStyle = ProcessWindowStyle.Hidden, CreateNoWindow = true, FileName = "cmd.exe"
});
BenVlodgi
  • 2,135
  • 1
  • 13
  • 26
  • Can you elaborate on these arguments? – Chad Nov 08 '19 at 05:02
  • @Chad the `choice /C Y /N /D Y /T 3` waits for 3 seconds then it will proceed to delete the application – newbieguy Mar 14 '20 at 06:36
  • in some cases `Assembly.GetExecutingAssembly().CodeBase` is better than `Application.ExecutablePath` (look the discussions here to this answer: https://stackoverflow.com/a/3991953/1574221) – marsh-wiggle May 11 '21 at 18:04
  • I personally prefer `Process.GetCurrentProcess().MainModule.FileName` Also please note that this code should either be followed by `Application.Exit()` or be placed in closing events – Couitchy Jun 27 '21 at 14:08
11

You must make sure, that your application is already closed when you want to delete the file. I would suggest something similar to the following one - you will need some modifications of course.

The following example works on windows and needs to be modified for other operating systems.

/// <summary>
/// Represents the entry point of our application.
/// </summary>
/// <param name="args">Possibly spcified command line arguments.</param>
public static void Main(string[] args)
{
    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");
}
Markus Safar
  • 6,324
  • 5
  • 28
  • 44
  • what is `echo j` used for? – newbieguy Mar 14 '20 at 06:27
  • Actually you can also try to use `del /F /Q'. `echo j` is used to pass it as input to `del /F` which represents _Ja_ in the German language. If your OS is an English one, you might need to use `echo y`. The whole thing is a workaround in case `del /Q` will not do it's thing correctly. – Markus Safar Mar 14 '20 at 08:42
4

It cannot delete itself while it is running, because its executable and library files will be locked. You could write a second program that takes in a process ID as an argument, waits for that process to die, and then deletes the first program. Embed that as a resource in your main application, then extract it to %TEMP%, run, and exit.

This technique is usually used in combination with automatic updaters, and it's definitely not fool-proof.

Mike Strobel
  • 25,075
  • 57
  • 69
3

It's not possible for the program to delete itself in general. Think about it from the perspective of taskmgr.

You see myprogram.exe running, and myprogram.exe tries to remove myprogram.exe An issue I can think of is that myprogram.exe is already running, resulting in an access issue.

That's why we see un-installation programs to remove everything. It operates as a separate executable.

ddavison
  • 28,221
  • 15
  • 85
  • 110
1

Yes. For example start a timed batch job to delete your exe after it has terminated. However you can't make sure that your exe is really deleted.

You can't delete your exe while it is running.

This won't work:

System.IO.File.Delete(System.AppDomain.CurrentDomain.FriendlyName);
Sam Hanley
  • 4,707
  • 7
  • 35
  • 63
Attila
  • 3,206
  • 2
  • 31
  • 44
0

Try something like this:

using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Threading;
//Include a reference to system

class MyClass {
  static void Main() {
    InitiateSelfDestructSequence();
    Thread.Sleep(10000);
  }
  static void InitiateSelfDestructSequence() {
    string batchScriptName = "BatchScript.bat";
    using (StreamWriter writer = File.AppendText(batchScriptName)) {
      writer.WriteLine(":Loop");
      writer.WriteLine("Tasklist /fi \"PID eq " + Process.GetCurrentProcess().Id.ToString() + "\" | find \":\"");
      writer.WriteLine("if Errorlevel 1 (");
      writer.WriteLine("  Timeout /T 1 /Nobreak");
      writer.WriteLine("  Goto Loop");
      writer.WriteLine(")");
      writer.WriteLine("Del \"" + (new FileInfo((new Uri(Assembly.GetExecutingAssembly().CodeBase)).LocalPath)).Name + "\"");
    }
    Process.Start(new ProcessStartInfo() { Arguments = "/C " + batchScriptName + " & Del " + batchScriptName, WindowStyle = ProcessWindowStyle.Hidden, CreateNoWindow = true, FileName = "cmd.exe" });
  }
}