我怎样才能让我的.NET应用程序自己擦除?

我怎样才能让我的C#应用​​程序擦除自己(自毁)? 以下是我认为可能有效的两种方法:

  • 提供另一个删除主程序的程序。 但是,删除程序如何被删除呢?
  • CMD创build一个进程,等待几秒钟,然后删除您的文件。 在这几秒钟内,你closures你的应用程序。

这两种方法似乎效率低下。 我有一种感觉,有一些内置的标志或Windows中允许这样的东西。 我应该怎么做? 另外,你可以提供一些示例代码?

更新:谢谢你所有的答案! 我要去尝试他们,看看我能得到什么。

首先,有人问我为什么要我的应用程序来做到这一点。 答案就在这里:前几天,我阅读了Joel Spolsky在其博客上发布的“Aardvark项目规范”,并提到客户端应用程序会在远程会话后自行删除。 我想知道这是如何工作的,以及如果我需要这样做,我可以完成这样的壮举。

以下是对build议的一些概述:

  • 创build一个registry项,告诉Windows在重新启动时删除该文件
  • 使用ping命令启动CMD,等待几秒钟,然后删除文件

当然,这两者都有其缺点,正如评论中所概述的那样。

但是,下面列出的这种方法是可行的吗?

有两个可执行文件:Program.exe和Cleaner.exe。 前者是程序本身,后者是删除Program.exe和本身的应用程序(如果它被加载到内存中,就像我将要解释的那样)。 Program.exe(有依赖项)是否可以将所有没有任何依赖关系的Cleaner.exe 加载 到内存中并运行?

如果这是可能的,Cleaner.exe是否可以打包到Program.exe中,然后加载到内存中,然后运行?

有一个MoveFileEx API,当给定MOVEFILE_DELAY_UNTIL_REBOOT标志时,将在下一次系统启动时删除指定的文件。

有一个很好的CodeProject文章关于这个话题。

编辑:基本上这是一个简单的cmd调用,将在几秒钟后删除指定的文件。

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

只要您需要机器上的实际存在,您将永远无法保证这一切都能正常工作。 例如:

  • 如果应用程序在尝试删除资源时未及时发布资源,该怎么办? 发生错误,应用程序仍然存在。
  • 一个应用程序开始另一个应用程序的行为,然后删除第一个应用程序是非常可疑的AV视角。 你很可能在用户的机器上触发防御措施,这可能会杀死正在试图杀死你的原始应用程序的进程。
  • 如果您在重新启动时执行了类似于删除文件的操作,那么如果用户在两者之间移动文件或进行复制,该怎么办? 它不在原来的位置,应用程序仍然存在。

如果您的应用程序需要这种安全级别,请考虑将其托管在您控制的计算机上(例如,通过提供Web服务并让存根客户端以这种方式访问​​它)。

在一个有点相关的说明中,也有人试图推测(1)需要在别人的机器上实际存在的人的动机,以及(2)想要删除应用程序存在的证据。

对@Bobby答案进行更正,以防人们发现它有用 – 可执行路径需要引用。 另外,下面是将cmd.exe窗口设置为隐藏状态(否则会以黑色控制台窗口的形式闪烁)并转换为不依赖于System.Windows.Forms程序集(应用程序类)的运行。

 
 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(信息).Dispose();
 Environment.Exit(0);

也有FileOptions.DeleteOnClose ,但是这需要文件打开写入。 你也许可以用这样的一个序列来做(未经测试):

  • 程序以Original.exe启动,并从(自己的名字)检测到它需要触发自毁功能。
  • Original.exe使用FileOptions.DeleteOnClose创建一个新文件Temp.exe ,并将其自己的内容复制到它,但不关闭它
  • Original.exe打开Temp.exe的第二个只读句柄,并关闭第一个写入句柄。 只读句柄可以与执行句柄共存,同时保持文件打开以延迟自动删除。
  • Original.exe启动Temp.exe Temp.exe会检测到它已经从临时目录启动并绕过自毁程序并继续正常操作。
  • Original.exe退出(将其只读句柄带到Temp.exe )。
  • Temp.exe继续运行。 当它退出时, Temp.exe文件将不再被使用,因此它将被自动删除。

编辑#2 :其实我不认为这是可能的,因为它依赖内核打开文件与FILE_SHARE_DELETE标志,这是不太可能的。

按NJ排序其他代码不起作用,所以它很简单,如果你创建浴文件循环到del应用程序和批处理文件本身你可以使用takkill命令杀死进程,如果你不想使用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 one is not 3d parts ov one I5 ~~~~~~~~~~~~~~~~~~~~~~~~~ I5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

想想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 + "\""); 

;>

我知道反射器删除自己,如果你使用旧版本,并选择不更新。 你可能会试图找出它的作用。 我会从FileMon开始,看看它是否会产生任何进程来实现这一点。

由于我的应用程序(一个Windows服务)通过Windows安装程序安装,我自我删除使用此:

 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) 

对不起 – 这是在VB中,但它应该很容易转换为C#。

在Windows 7和8中运行,**确保您使用管理员权限运行应用程序,否则将会出现错误。

这个代码存在于其他地方,所以我不能完全相信我发现我通过添加“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(); }