windows 如何让我的 .NET 应用程序自行擦除?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2245201/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 13:54:59  来源:igfitidea点击:

How can I make my .NET application erase itself?

c#.netwindowsdelete-fileself-destruction

提问by Maxim Zaslavsky

How can I make my C# app erase itself (self-destruct)? Here's two ways that I think might work:

如何让我的 C# 应用程序自行擦除(自毁)?以下是我认为可能有效的两种方法:

  • Supply another program that deletes the main program. How is this deleter program deleted then, though?
  • Create a process to CMD that waits a few seconds then deletes your file. During those few seconds, you close your application.
  • 提供另一个删除主程序的程序。但是,这个删除程序是如何删除的呢?
  • 创建一个 CMD 进程,等待几秒钟然后删除您的文件。在这几秒钟内,您关闭了应用程序。

Both of those methods seem inefficient. I have a feeling that there's some built-in flag or something in Windows that allows for such stuff. How should I do it? Also, can you provide some sample code?

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

UPDATE:Thanks for all your answers! I'm going to try them, and see where that gets me.

更新:感谢您的所有回答!我要试试他们,看看这让我在哪里。

First of all, some people have asked why I'd want my app to do this. Here's the answer: a few days ago, I read the Project Aardvark spec that Joel Spolsky posted on his blog, and it mentioned that the client app would delete itself after the remote session. I'm wondering how this works, and how, if I ever need to do this, I can accomplish such a feat.

首先,有些人问我为什么希望我的应用程序这样做。答案如下:几天前,我阅读了 Joel Spolsky 在其博客上发布的 Project Aardvark 规范,其中提到客户端应用程序将在远程会话后自行删除。我想知道这是如何工作的,以及如果我需要这样做,我如何才能完成这样的壮举。

Here's a little overview of what's been suggested:

以下是对建议内容的简要概述:

  • Create a registry entry that tells Windows to delete the file on reboot
  • Launch CMD with a ping command to wait a few seconds and then delete the file
  • 创建一个注册表项,告诉 Windows 在重新启动时删除该文件
  • 使用 ping 命令启动 CMD 等待几秒钟,然后删除文件

Both of those, of course, have their disadvantages, as outlined in the comments.

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

However, would such a method as outlined below work?

但是,下面概述的这种方法是否有效?

There are two executables: Program.exe and Cleaner.exe. The former is the program itself, the latter is the app that deletes Program.exe and itself (if it's loaded into memory, as I'm about to explain). Is it possible for Program.exe (which has dependencies) to loadall of Cleaner.exe, which doesn't have any dependencies, into memoryand run it?

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

If this is possible, could Cleaner.exe be packaged inside Program.exe, loaded into memory, and run?

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

采纳答案by Anton Gogolev

There's a MoveFileExAPI, which, when given a MOVEFILE_DELAY_UNTIL_REBOOTflag, will delete specified file on next system startup.

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

回答by Bobby

There's a great CodeProject Articleabout this topic.

一篇关于这个主题的很棒的CodeProject 文章

Edit:Basically it's a simple cmd-call which will delete the specified files after some seconds.

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

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

回答by John Feminella

You will never be able to guarantee that this will work, as long as you require a physical presence on the machine.For example:

只要您需要在机器上实际存在,您就永远无法保证这会起作用。例如:

  • What if the app fails to release a resource in a timely fashion while you're trying to delete it? An error occurs, and the app remains.
  • The behavior of one app starting another which then deletes the first app is very suspiciousfrom an AV perspective. You are likely to trigger defenses on a user's machine which may kill the process that's trying to kill your original app.
  • If you do something like delete a file at reboot, what if the user moves your file in between or makes a copy? It's not in the original spot anymore, and the app remains.
  • 如果应用程序在您尝试删除资源时未能及时释放资源怎么办?发生错误,应用程序仍然存在。
  • 从 AV 的角度来看,一个应用程序启动另一个应用程序然后删除第一个应用程序的行为非常可疑。您可能会在用户的机器上触发防御措施,这可能会终止试图终止您的原始应用程序的进程。
  • 如果您在重新启动时执行诸如删除文件之类的操作,如果用户将您的文件移动到它们之间或进行复制怎么办?它不再在原来的位置,应用程序仍然存在。

If your application requires this level of security, consider hosting it on a machine you control (e.g., by providing a web service and letting a stub client access it that way).

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

On a somewhat related note, one is also tempted to speculate about the motives of someone who (1) requires a physical presence on someone's machine and (2) wants to delete the evidence that the app existed.

在有些相关的说明中,人们也很想推测某人的动机,他 (1) 需要在某人的机器上实际存在并且 (2) 想要删除该应用程序存在的证据。

回答by Lev

A correction to @Bobby answer, in case people will find it useful - executable path needs to be quoted. Additionally, below is setting cmd.exe window to be hidden (otherwise it flashes as a black console window) and converted to run without relying on System.Windows.Forms assembly (the Application class).

对@Bobby 答案的更正,以防人们发现它有用 - 需要引用可执行路径。此外,下面将 cmd.exe 窗口设置为隐藏(否则它会闪烁为黑色控制台窗口)并转换为不依赖 System.Windows.Forms 程序集(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);

回答by cOd3r

sorted by NJ c# the other codes does not work so its simple if u create bath file that loops to del application and the batch file itself u can use takkill command to kill the process if u dont want to use application.close method

由 NJ c# 排序,其他代码不起作用,所以它很简单,如果你创建循环到 del 应用程序和批处理文件本身的 Bath 文件你可以使用 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

` Th3 3e3 one不是I5的3d零件~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

回答by Homer Simpsons

Think CMD

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

;>

;>

回答by finnw

There is also FileOptions.DeleteOnClose, but that requires the file to be open for writing. You might be able to do it with a sequence like this (untested):

还有FileOptions.DeleteOnClose,但这需要打开文件进行写入。您可能可以使用这样的序列(未经测试)来执行此操作:

  • Program launches as Original.exe, and detects (from its own name) that it needs to trigger the self-destruct function.
  • Original.execreates a new file Temp.exewith FileOptions.DeleteOnCloseand copies its own content into it, but does not close it yet
  • Original.exeopens a second, read-only handle to Temp.exeand closes the first write handle. The read-only handle can co-exist with an execute handle, whilst keeping the file open to delay auto-deletion.
  • Original.exelaunches Temp.exe. Temp.exedetects that it has been launched from the temp directory and bypasses the self-destruct sequence and continues normal operation.
  • Original.exeexits (taking its read-only handle to Temp.exewith it.)
  • Temp.execontinues running. When it exits, the file Temp.exewill no longer be in use so it will be deleted automatically.
  • 程序启动为Original.exe,并检测(从它自己的名称)它需要触发自毁功能。
  • Original.exe创建一个新的文件Temp.exeFileOptions.DeleteOnClose并复制其自己的内容进去,但不会关闭它尚未
  • Original.exe打开第二个只读句柄Temp.exe并关闭第一个写句柄。只读句柄可以与执行句柄共存,同时保持文件打开以延迟自动删除。
  • Original.exe发射Temp.exeTemp.exe检测到它已从临时目录启动并绕过自毁序列并继续正常运行。
  • Original.exe退出(带上它的只读句柄Temp.exe。)
  • Temp.exe继续运行。当它退出时,该文件Temp.exe将不再被使用,因此它会被自动删除。


Edit #2: Actually I don't think this is possible, because it relies on the kernel opening the file with the FILE_SHARE_DELETEflag, which is unlikely.

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

回答by Austin Thompson

I know reflector deletes itself if you use an old version and choose not to update. You might try to figure out what it does. I would start with FileMon and see if it spawns any processes to achieve this.

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

回答by Aaron C. de Bruyn

Since my application (a Windows Service) is installed via the Windows Installer, I self-delete using this:

由于我的应用程序(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)

Sorry--it's in VB, but it should be easily convertible to C#.

抱歉——它在 VB 中,但它应该很容易转换为 C#。

回答by hransom

Works in Windows 7 & 8, **ENSURE you run your application with admin privileges or you will get an error.

适用于 Windows 7 和 8,**确保您以管理员权限运行您的应用程序,否则您将收到错误消息。

This code exists elsewhere so I can't take full credit I found I made it work for me by adding "Application.Exit();"

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