2009-08-20 7 views
27

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

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

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

George.

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

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

Применение выполняется как folowed:

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

Вы спрашивали о проблемах с самим OneClick? Может быть, это решит вопрос. – Christian13467

+0

Не сам OneClick. Я обновил вопрос и добавил прикладную программу для повышения точности. – George

ответ

30

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

Фрагмент кода взяты из this article

+0

Спасибо за статью. Dunno, почему я не смог найти его: S – George

+2

Что делать, если приложение не закрывается через 3 секунды? –

+0

@AlexZhukovskiy таймаут в примере не определяет, сколько времени система должна ждать, прежде чем пытаться удалить приложение, таймаут просто вызывает значение по умолчанию, чтобы заставить приложение закрыться. Вы просто указываете на командную строку, которая после процесса существует, запустите файл [del] (https://www.microsoft.com/resources/documentation/windows/xp/all/proddocs/en-us/del.mspx? mfr = true). – James

0

Mhh поэтому позвольте мне получить это прямо. У вас есть приложение application.exe и приложение updater.exe для обновления.

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

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

+0

Я добавил приложение для точности. – George

0

вашей второй линии может быть

Updater: Star -> do it's work -> start Application Executable -> Updater Exits -> Application deletes your Updater.exe 
+0

Я думал об этом, но мне нужно обновить, чтобы удалить себя. – George

+0

Интересно. Вы боретесь с решением, которое, похоже, не работает. В чем проблема? ПОЧЕМУ вы хотите, чтобы программа обновления удалила себя и почему не приложение? – 2009-08-20 11:38:02

2

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

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

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

Применение: Пуск -> [Удалить старую программу обновления, если присутствует] -> ...

5

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

Для полной обработки и других параметров вы должны прочитать the definitive treatment of self deleting EXEs. Образцы кода находятся в C (или ASM), но должны быть p/invokable.

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

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

Once application.exe выходов, updater.exe имеет дескриптор файла в 1. При Updater. exe выходит, он падает до 0 и должен быть удален.

+3

К сожалению, это не работает, потому что процесс должен быть запущен с помощью 'FILE_SHARE_DELETE' - какого процесса.Пуск не работает. Затем он не запускает процесс, потому что файл все еще открыт (и его нельзя закрыть, потому что он удалит его). – urbanhusky

8

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

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() 
    { 
     ..... 
    } 
} 
+0

Просто не «удалить .../y», но «del .../Q» – Boogier

-1
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» для окна формы приложения.

+0

Кажется довольно похожим на более ранний пакетный подход к файлу, но он может бесконечно контурно работать в условиях ошибки, что не кажется мудрым. –

Смежные вопросы