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

发布于 2024-08-21 07:42:08 字数 893 浏览 4 评论 0原文

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

  • 提供另一个删除主程序的程序。那么这个删除程序是如何删除的呢?
  • 创建一个 CMD 进程,等待几秒钟,然后删除您的文件。在那几秒钟内,您关闭了应用程序。

这两种方法似乎效率都很低。我有一种感觉,Windows 中有一些内置标志或其他东西允许执行此类操作。我该怎么做呢?另外,您能提供一些示例代码吗?

更新:感谢您的所有回答!我会尝试一下,看看对我有什么好处。

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

以下是对建议内容的一些概述:

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

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

然而,下面概述的这种方法有效吗?

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

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

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

  • 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.

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?

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.

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

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 load all of Cleaner.exe, which doesn't have any dependencies, into memory and run it?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(11

灵芸 2024-08-28 07:42:08

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

There's a MoveFileEx API, which, when given a MOVEFILE_DELAY_UNTIL_REBOOT flag, will delete specified file on next system startup.

迷途知返 2024-08-28 07:42:08

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

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

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

There's a great CodeProject Article about this topic.

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

Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " + Application.ExecutablePath); 
Application.Exit();
Saygoodbye 2024-08-28 07:42:08

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

  • 如果应用程序无法及时释放资源,而您却无法及时释放资源,该怎么办?正在尝试删除它?发生错误,但应用程序仍然存在。
  • 从反病毒软件的角度来看,一个应用程序启动另一个应用程序然后删除第一个应用程序的行为非常可疑。您可能会触发用户计算机上的防御,这可能会杀死试图杀死您的原始应用程序的进程。
  • 如果您执行诸如在重新启动时删除文件之类的操作,那么如果用户在中间移动您的文件或制作副本怎么办?它不再位于原来的位置,并且应用程序仍然存在。

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

与此相关的是,人们还很想猜测某人的动机:(1) 需要实际存在于某人的计算机上,并且 (2) 想要删除该应用程序存在的证据。

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 suspicious from 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.

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).

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.

笔落惊风雨 2024-08-28 07:42:08

对@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);

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).

 
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);
风苍溪 2024-08-28 07:42:08

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

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

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

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):

  • Program launches as Original.exe, and detects (from its own name) that it needs to trigger the self-destruct function.
  • Original.exe creates a new file Temp.exe with FileOptions.DeleteOnClose and copies its own content into it, but does not close it yet
  • Original.exe opens a second, read-only handle to Temp.exe and 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.exe launches Temp.exe. Temp.exe detects that it has been launched from the temp directory and bypasses the self-destruct sequence and continues normal operation.
  • Original.exe exits (taking its read-only handle to Temp.exe with it.)
  • Temp.exe continues running. When it exits, the file Temp.exe will no longer be in use so it will be deleted automatically.

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

莳間冲淡了誓言ζ 2024-08-28 07:42:08

按新泽西州排序
时间:2019-03-17 标签: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 1 不是 3d 零件 ov 1
I5
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

        `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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

℡寂寞咖啡 2024-08-28 07:42:08

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

;>

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

;>

比忠 2024-08-28 07:42:08

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

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.

梦幻之岛 2024-08-28 07:42:08

适用于 Windows 7 和 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();
}

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

This code exists elsewhere so I can't take full credit I found I made it work for me by adding "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();
}
笑叹一世浮沉 2024-08-28 07:42:08

这是 Uninstall.exe:

  1. 关机。

  2. 等待 3 秒。

  3. 如果该任务仍在运行,请尝试终止该任务。

  4. 等待 3 秒。

  5. 删除其中包含Uninstall.exe的应用程序目录。

     public void Uninstall()
     {
         var delPath = AppDomain.CurrentDomain.BaseDirectory;
    
         var procId = Process.GetCurrentProcess().Id;
    
         var psi = 新的 ProcessStartInfo
         {
             文件名 = "cmd.exe",
             参数 = $"/C 超时 3 & Taskkill /F /PID {procId} & 超时 3 & rd /s /q \"{delPath}\"",
             创建无窗口 = true,
             WindowStyle = ProcessWindowStyle.Hidden
         };
         过程.开始(psi);
         Application.Current.Shutdown();
     }
    

This is the Uninstall.exe:

  1. Shutdown.

  2. Wait for 3 sec.

  3. Try to kill that task if it is still running.

  4. Wait for 3 sec.

  5. Delete the app directory with the Uninstall.exe in it.

     public void Uninstall()
     {
         var delPath = AppDomain.CurrentDomain.BaseDirectory;
    
         var procId = Process.GetCurrentProcess().Id;
    
         var psi = new ProcessStartInfo
         {
             FileName = "cmd.exe",
             Arguments = 
    quot;/C timeout 3 & Taskkill /F /PID {procId} & timeout 3 & rd /s /q \"{delPath}\"",
             CreateNoWindow = true,
             WindowStyle = ProcessWindowStyle.Hidden
         };
         Process.Start(psi);
         Application.Current.Shutdown();
     }
    
懒的傷心 2024-08-28 07:42:08

由于我的应用程序(Windows 服务)是通过 Windows Installer 安装的,因此我使用以下命令自行删除:

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#。

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

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#.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文