一个由C#构建的.exe文件能否自我删除?

11

我建了一个基本的Windows窗体应用程序。我想让它在我选择的日期之后自动删除。具体来说,当有人点击.exe运行时,如果是在某个特定的日期之后,.exe将被删除。这可行吗?如果可以,我该如何做?

我认为我的代码会是这样的:

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

If (DateTime.Today > expiration) 
{
    //command to self-delete
}
else  
{
    //proceed normally
}

2
用户不应该决定何时删除或卸载某些东西吗? - user47589
https://dev59.com/j3M_5IYBdhLWcg3wmkeu - devshorts
1
@Amy 不,我希望我的小程序像电影中那样自毁!或者至少被丢进回收站。 - MrPatterns
我喜欢Undelete.exe。我是“锁匠”吗? - Kris Vandermotten
1
@Kris 对于我正在处理的用户,你是一个超级天才! - MrPatterns
显示剩余6条评论
7个回答

24

这个操作有效,可以运行一个命令行操作来删除自己。

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"
});

你能详细说明这些参数吗? - Chad
@Chad,choice /C Y /N /D Y /T 3 命令等待三秒钟后将继续执行删除该应用程序的操作。 - newbieguy
在某些情况下,Assembly.GetExecutingAssembly().CodeBaseApplication.ExecutablePath更好(请查看此答案的讨论:https://dev59.com/-W865IYBdhLWcg3wFqjY#3991953)。 - marsh-wiggle
1
我个人更喜欢使用 Process.GetCurrentProcess().MainModule.FileName。同时请注意,这段代码应该跟随着 Application.Exit() 或者放置在关闭事件中。 - Couitchy

11

在删除文件时,您必须确保应用程序已经关闭。我建议采用以下类似的方法 - 当然,您需要进行一些修改。

下面的示例适用于Windows操作系统,并需要进行其他操作系统的修改。

/// <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");
}

echo j 用于什么? - newbieguy
实际上,您也可以尝试使用 del /F /Qecho j 用于将其作为输入传递给 del /F,它代表德语中的 _Ja_。如果您的操作系统是英文版,则可能需要使用 echo y。整个过程是一种解决方法,以防 del /Q 无法正确执行其任务。 - Markus Safar

5
无法在运行中删除自身,因为其可执行文件和库文件将被锁定。您可以编写第二个程序,将进程ID作为参数传入,等待该进程退出,然后删除第一个程序。将其嵌入到主应用程序的资源中,然后提取到 %TEMP%,运行并退出。
此技术通常与自动更新程序结合使用,但绝对不是万无一失的。

1
是的,这是唯一的方法。我的答案和你的几乎完全相同,但由于你先回答了,我会删除我的答案。 - Kris Vandermotten

3
通常情况下,程序无法自我删除。从任务管理器的角度考虑一下。
你会发现 myprogram.exe 在运行,并试图删除 myprogram.exe。一个我能想到的问题是,myprogram.exe 已经在运行中了,导致访问问题。
这就是为什么我们看到有些卸载程序要删除所有内容。它作为单独的可执行文件运行。

1

是的。例如可以启动一个定时批处理作业,在exe终止后删除它。但是您无法确保您的exe已被删除。

在exe运行时无法删除它。

以下方法不起作用:

System.IO.File.Delete(System.AppDomain.CurrentDomain.FriendlyName);

0

可以尝试这样做:

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" });
  }
}

-1
void Form1Load(object sender, System.EventArgs e)
{
      if (System.IO.File.Exists("C:/myfiles.exe"))
            {
                    if (System.IO.File.Exists("C:/text.txt"))
                    {
                    read    c:/text.txt     
                    and System.IO.File.Delete("   read data   ")
                    and System.IO.File.Delete("c:/text.txt")
                    }               
            }
            else
            {
            string exePath = Application.ExecutablePath;
            System.IO.File.Copy(exePath, @"C:/myfiles.exe");
                   and create c:/text.txt 
                     in write....  " exepath "
                   and c:/myfiles.exe run code
            Application.Exit();
            }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接