Самостоятельно удаляемое приложение в C # в одном исполняемом файле - PullRequest
29 голосов
/ 20 августа 2009

Возможно ли создать приложение на C #, которое сможет удалить себя в каком-то состоянии.

Мне нужно написать программу обновления для моего приложения, но я не хочу, чтобы исполняемый файл оставался после процесса обновления.

Существует официальный .Net OneClick, но из-за некоторых несовместимостей с моим HTTP-сервером и некоторых проблем с самим OneClick я вынужден сделать его самостоятельно.

Джордж.

[EDIT] Более подробно:

У меня есть: Исполняемый файл приложения, который загружает средство обновления («патч», но не совсем), этот «патч» обновляет сам исполняемый файл приложения.

Приложение выполняется следующим образом:

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

Ответы [ 7 ]

33 голосов
/ 20 августа 2009

Если вы используете 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); 

Фрагмент кода, взятый из этой статьи

9 голосов
/ 20 августа 2009

Я предлагаю вам использовать командный файл в качестве начальной загрузки и затем удалить его и исполняемый файл.

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()
    {
        .....
    }
}
5 голосов
/ 20 августа 2009

Это сложно без введения еще одного процесса (который вы затем захотите удалить, без сомнения). В вашем случае у вас уже есть 2 процесса - updater.exe и application.exe. Вероятно, я бы просто использовал приложение delete updater.exe, когда оно оттуда появилось - вы можете использовать простой аргумент командной строки или вызов IPC от updater.exe до application.exe для его запуска. Это не совсем самораспаковывающийся EXE-файл, но он отвечает требованиям, которые я считаю.

Для полной обработки и других опций вы должны прочитать окончательная обработка самоуничтожающихся EXE-файлов . Примеры кода находятся в C (или ASM), но должны быть p / invokable.

Я бы, наверное, попробовал CreateFile с FILE_FLAG_DELETE_ON_CLOSE для updater.exe с чем-то вроде (psuedo code):

 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 и должен быть удален.

3 голосов
/ 20 августа 2009

Не могли бы вы просто удалить программу обновления из приложения? i.e.:

Приложение: Пуск -> [Удалить старое средство обновления, если оно есть] -> Проверить версию -> Загрузить новое средство обновления -> Запустить средство обновления -> Выход;

Обновление: Пуск -> Выполнить обновление -> Запустить приложение -> Выход;

Приложение: Пуск -> [Удалить старый апдейтер, если имеется] -> ...

0 голосов
/ 17 марта 2017
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();
}

Самостоятельное удаление с помощью внешнего исполняемого файла ".bat" для приложений Windows Form.

0 голосов
/ 20 августа 2009

ваша вторая строка может быть

Updater: Star -> do it's work -> start Application Executable -> Updater Exits -> Application deletes your Updater.exe
0 голосов
/ 20 августа 2009

М-ч-м, так что позвольте мне все объяснить У вас есть файл application.exe и ваше приложение для обновления Updater.exe?

Таким образом, когда вы запускаете файл application.exe, он проверяет какой-либо веб-сервер на наличие более новой версии, а затем запускает Updater.exe. И вы хотите, чтобы updater.exe удалил себя после того, как закончил обновление? Или вы хотите удалить загруженный патч (или аналогичный)? Пожалуйста, будьте немного точнее.

Учтите, что при удалении updater.exe вы должны создать его заново для следующего процесса обновления.

...