32

是否可以在 C# 中创建一个能够在某些情况下自行删除的应用程序。

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

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

乔治。

[编辑] 更多细节:

我有:应用程序可执行文件下载更新程序(“补丁”,但不完全是)这个“补丁”更新应用程序可执行文件本身。

应用程序执行如下:

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);
4

7 回答 7

35

如果您使用 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); 

摘自本文的代码片段

于 2009-08-20T11:17:24.293 回答
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()
    {
        .....
    }
}
于 2009-08-20T18:04:05.657 回答
5

如果不引入另一个过程(毫无疑问,您随后也想删除),这很棘手。在您的情况下,您已经有 2 个进程 - updater.exe 和 application.exe。当它从那里产生时,我可能只是让应用程序删除 updater.exe - 您可以使用简单的命令行参数,或从 updater.exe 到 application.exe 的 IPC 调用来触发它。这不完全是一个自我删除的EXE,但满足了我认为的要求。

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

我可能会尝试使用类似(伪代码)的for updater.exe CreateFile :FILE_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");

一旦 application.exe 退出,updater.exe 的文件句柄为 1。当 updater.exe 退出时,它会下降到 0,应该被删除。

于 2009-08-20T11:56:44.887 回答
3

您不能简单地从应用程序中删除更新程序吗?IE:

应用程序:开始 -> [删除旧更新程序,如果存在] -> 检查版本 -> 下载新更新程序 -> 启动更新程序 -> 退出;

更新程序:开始 -> 执行更新 -> 启动应用程序 -> 退出;

应用程序:开始 -> [删除旧更新程序,如果存在] -> ...

于 2009-08-20T11:32:06.417 回答
0

嗯,所以让我直截了当。您有一些 application.exe 和您的更新程序应用程序 updater.exe?

因此,当您启动 application.exe 时,它​​会检查一些网络服务器是否有较新的版本,然后启动 updater.exe。并且您希望 updater.exe 在完成更新后自行删除?或者你想删除下载的补丁(或类似的)?请准确一点。

考虑到当您删除 updater.exe 时,您必须为下一次更新过程重新创建它。

于 2009-08-20T11:11:26.333 回答
0

你的第二行可以是

Updater: Star -> do it's work -> start Application Executable -> Updater Exits -> Application deletes your Updater.exe
于 2009-08-20T11:29:53.223 回答
0
public void uninstall() {
    string app_name = Application.StartupPath + "\\" + Application.ProductName + ".exe";
    string bat_name = app_name + ".bat";

    string bat = "@echo off\n"
        + ":loop\n"
        + "del \"" + app_name + "\"\n"
        + "if Exist \"" + app_name + "\" GOTO loop\n"
        + "del %0";

    StreamWriter file = new StreamWriter(bat_name);
    file.Write(bat);
    file.Close();

    Process bat_call = new Process();
    bat_call.StartInfo.FileName = bat_name;
    bat_call.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
    bat_call.StartInfo.UseShellExecute = true;
    bat_call.Start();

    Application.Exit();
}

由 Windows 窗体应用程序的外部可执行文件“.bat”自行删除。

于 2017-03-17T00:37:09.157 回答