C#中的自删除应用程序在一个可执行文件中

Geo*_*rge 29 .net c# self-updating self-destruction

是否可以在C#中创建一个能够在某些条件下删除自己的应用程序.

我需要为我的应用程序编写更新程序,但我不希望在更新过程后留下可执行文件.

有一个官方的.Net OneClick但由于与我的HTTP服务器有些不兼容以及OneClick本身的一些问题,我不得不自己制作一个.

乔治.

[编辑]更多细节:

我有:Application Executable下载更新程序("补丁",但不完全)这个"补丁"更新应用程序可执行文件本身.

应用程序执行如下:

Application: Start -> Check Version -> Download new Updater -> Start Updater -> exit;
Updater: Start -> do it's work -> start Application Executable -> self delete (this is where I get stuck);
Run Code Online (Sandbox Code Playgroud)

Jam*_*mes 34

如果使用Process.Start,则可以将Del参数和路径传递给要删除的应用程序.

ProcessStartInfo Info=new ProcessStartInfo();
Info.Arguments="/C choice /C Y /N /D Y /T 3 & Del "+
               Application.ExecutablePath;
Info.WindowStyle=ProcessWindowStyle.Hidden;
Info.CreateNoWindow=true;
Info.FileName="cmd.exe";
Process.Start(Info); 
Run Code Online (Sandbox Code Playgroud)

本文中获取的代码段

  • @James在`Process.Start`之后添加`Thread.Sleep(10000)`.不会删除可执行文件. (3认同)
  • 如果应用程序不会在3秒内关闭怎么办? (2认同)
  • @AlexZhukovskiy仍然不明白为什么你在这里讨论像终结器/类这样的东西 - [del](https://technet.microsoft.com/en-gb/library/cc771049.aspx)命令是一个系统命令启动**过程结束后."*我们不知道什么时候会完成*" - 是的,我们这样做,当进程返回退出代码时...... (2认同)
  • @JaySullivan并且完全可以预料到,因为您不再在执行代码时关闭应用程序 - 上述解决方案的目的是OP知道此时该过程即将被杀死.我完全理解一些应用程序更复杂,例如后台线程可能仍然在运行,但是规则仍然适用 - 你会跟踪这些并且一旦完成,那么你就可以运行代码了.从未建议上述解决方案将覆盖所有基础,当按预期使用它完成工作时. (2认同)

小智 9

我建议您使用批处理文件作为引导程序,然后删除自己和exe

public static class Updater
{
    public static void Main() 
    {   
        string path = @"updater.bat";

        if (!File.Exists(path)) 
        {
            // Create a file to write to.
            using (StreamWriter sw = File.CreateText(path)) 
            {
                sw.WriteLine("updater.exe");
                sw.WriteLine("delete updater.exe /y");
                sw.WriteLine("delete updater.bat /y");
            } 

            System.Process.Start(path);   
        }
        else
        {
            RunUpdateProcess();
        }
    }

    private void RunUpdateProcess()
    {
        .....
    }
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*ett 5

如果没有引入另一个进程(你当然也希望删除,毫无疑问),这很棘手.在您的情况下,您已经有2个进程 - updater.exe和application.exe.我可能只是从那里生成应用程序删除updater.exe - 您可以使用简单的命令行arg,或从updater.exe到application.exe的IPC调用来触发它.这不是一个自我删除EXE,但满足我认为的要求.

对于完整治疗和其他选项,您应该阅读自我删除EXE的最终处理.代码示例使用C(或ASM),但应该是p/invokable.

我可能尝试使用updater.exe的CreateFileFILE_FLAG_DELETE_ON_CLOSE类似(伪造的代码):

 var h = CreateFile(
            "updater.exe", 
            GENERIC_READ | GENERIC_WRITE, 
            FILE_SHARE_DELETE, 
            NULL, 
            CREATE_NEW, 
            FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE
         );

 byte[] updaterBytes = GetUpdaterBytesFromWeb();
 File.WriteAllBytes("updater.exe", updaterBytes);

 Process.Start("updater.exe");
Run Code Online (Sandbox Code Playgroud)

一旦application.exe退出,updater.exe的文件句柄为1.当updater.exe退出时,它将降为0并应删除.

  • 不幸的是,这似乎不起作用,因为该过程必须以`FILE_SHARE_DELETE`开头 - Process.Start不这样做.然后它无法启动该进程,因为该文件仍处于打开状态(并且无法关闭它,因为这会将其删除). (3认同)