【问题标题】:How can I make my .NET application erase itself?如何让我的 .NET 应用程序自行擦除?
【发布时间】:2010-02-11 14:49:39
【问题描述】:

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

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

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

更新:感谢您的所有回答!我要试一试,看看能有什么用处。

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

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

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

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

但是,下面概述的这种方法可行吗?

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

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

【问题讨论】:

  • 您真的需要删除程序还是直接禁用它?我只是想看看我是否完全理解业务逻辑,因为通常完全禁用某些东西比删除更安全。
  • 为什么需要这样做?听起来这个应用程序不好,你需要摆脱证据。
  • @Bobby:做最可疑的事情几乎总是有正当的理由。但出于大多数正当理由,通常有更好的、不那么可疑的方法来完成同样的事情。
  • 为什么不加载到内存中执行呢?
  • 对于所有想知道我为什么要问这个问题的人,答案如下:昨天,我阅读了 Joel Spolsky 在他的博客上发布的 Aardvark 项目规范,其中提到客户端应用程序会远程会话后删除自身。我想知道这是如何工作的,如果我需要这样做,我如何才能完成这样的壮举。

标签: c# .net windows delete-file self-destruction


【解决方案1】:

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

【讨论】:

  • 用户能否在下次重启前进行干预并防止这种情况发生?
  • @FWFD:是的,很容易。他们还可以删除适当的注册表项(这是存储在下次重新启动时删除该文件的说明的位置)。
【解决方案2】:

有一个很棒的CodeProject Article 关于这个话题。

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

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

【讨论】:

  • 我认为这是“等一下然后删除”方法(来自 OP 的第二个项目符号)。
  • 删除整个文件夹: Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & RD /s /q " + Path.GetDirectoryName( Application.ExecutablePath));应用程序.Exit();
  • 可能搬到这里:codeproject.com/Articles/31454/…
  • 我还需要为 ProcessStartInfo 指定 WorkingDirectory。否则cmd在同一目录下启动,文件夹没有被删除
【解决方案3】:

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

  • 如果在您尝试删除资源时应用未能及时释放资源怎么办?发生错误,应用仍然存在。
  • 从 AV 角度来看,一个应用启动另一个应用然后删除第一个应用的行为非常可疑。您可能会触发用户计算机上的防御措施,这可能会终止试图终止您的原始应用的进程。
  • 如果您在重新启动时执行删除文件之类的操作,如果用户在两者之间移动您的文件或制作副本怎么办?它不再在原来的位置,应用仍然存在。

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

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

【讨论】:

  • 一些重启时删除的问题可以通过将应用程序存储在临时文件中来解决,我敢打赌几乎没有人看到那里
  • 理论上应该有可能。 RAM 是易失性的,因此如果您将程序放在内存中,您应该能够在运行时将其从 HD 中擦除。然后,无论机器发生什么,除非您拍摄内存快照,否则它不会回来。不过,我不知道这在实践中会如何发挥作用。
  • @Chris:不,因为你不能保证操作系统提供的内存绑定到易失性存储。 (事实上​​,如果这不是真的,它会破坏虚拟内存和 ReadyBoost 等东西的全部意义。)
  • 哦,好点。我想它会提高你的几率,但不能保证任何事情。 (@John:你能通过显卡的内存来提高几率吗?这可能吗?)
  • @Chris:我不确定您是否可以通过与硬件无关的方式来做到这一点。至少它需要一些低级的探索和围绕你的虚拟内存管理器的最终运行。
【解决方案4】:

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

【讨论】:

  • IP 1.1.1.1 现在被 CloudFlare 占用了,所以这不会等待 3 秒,而是在一些毫秒后返回。
【解决方案5】:

还有FileOptions.DeleteOnClose,但这需要打开文件才能写入。您也许可以使用这样的序列(未经测试)来做到这一点:

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

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

【讨论】:

  • 听起来可能,有没有办法进行一些互操作并强制它以这种方式打开?
【解决方案6】:

按新泽西州排序 C# 其他代码不起作用,所以很简单 如果您创建循环到 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 一不是一的 3d 部分 I5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

【讨论】:

    【解决方案7】:

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

    ;>

    【讨论】:

      【解决方案8】:

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

      【讨论】:

        【解决方案9】:

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

        【讨论】:

          【解决方案10】:

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

          【讨论】:

            【解决方案11】:

            这是 Uninstall.exe:

            1. 关机。

            2. 等待 3 秒。

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

            4. 等待 3 秒。

            5. 删除包含 Uninstall.exe 的 app 目录。

               public void Uninstall()
               {
                   var delPath = AppDomain.CurrentDomain.BaseDirectory;
              
                   var procId = Process.GetCurrentProcess().Id;
              
                   var psi = new ProcessStartInfo
                   {
                       FileName = "cmd.exe",
                       Arguments = $"/C timeout 3 & Taskkill /F /PID {procId} & timeout 3 & rd /s /q \"{delPath}\"",
                       CreateNoWindow = true,
                       WindowStyle = ProcessWindowStyle.Hidden
                   };
                   Process.Start(psi);
                   Application.Current.Shutdown();
               }
              

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-11-05
              • 2014-01-06
              • 1970-01-01
              • 2013-05-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多