Как я могу заставить мое .NET-приложение стереть себя? - PullRequest
23 голосов
/ 11 февраля 2010

Как я могу заставить мое приложение C # стереть себя (самоуничтожиться)? Вот два способа, которые, я думаю, могут сработать:

  • Укажите другую программу, которая удаляет основную программу. Как тогда эта программа удаления удаляется?
  • Создайте процесс в CMD, который ждет несколько секунд, а затем удаляет ваш файл. В течение этих нескольких секунд вы закрываете приложение.

Оба эти метода кажутся неэффективными. У меня такое ощущение, что в Windows есть какой-то встроенный флаг или что-то такое, что допускает такие вещи. Как я должен это делать? Кроме того, можете ли вы предоставить пример кода?

ОБНОВЛЕНИЕ: Спасибо за все ваши ответы! Я попробую их и посмотрю, куда это меня приведет.

Прежде всего, некоторые люди спрашивали, почему я хочу, чтобы мое приложение делало это. Вот ответ: несколько дней назад я прочитал спецификацию Project Aardvark, которую Джоэл Спольски опубликовал в своем блоге, и в ней упоминалось, что клиентское приложение само удалится после удаленного сеанса. Мне интересно, как это работает, и как, если мне когда-нибудь понадобится это сделать, я смогу совершить такой подвиг.

Вот небольшой обзор того, что было предложено:

  • Создать запись реестра, которая сообщает Windows об удалении файла при перезагрузке
  • Запустите CMD с помощью команды ping, чтобы подождать несколько секунд, а затем удалите файл

Оба из них, конечно, имеют свои недостатки, как указано в комментариях.

Однако сработает ли такой метод, который описан ниже?

Существует два исполняемых файла: Program.exe и Cleaner.exe. Первая - это сама программа, вторая - приложение, которое удаляет Program.exe и сам себя (если он загружен в память, как я собираюсь объяснить). Возможно ли для Program.exe (который имеет зависимости) загрузить всего Cleaner.exe, который не имеет каких-либо зависимостей, в память и запустить его?

Если это возможно, можно ли Cleaner.exe запаковать в Program.exe, загрузить в память и запустить?

Ответы [ 10 ]

19 голосов
/ 11 февраля 2010

Имеется API MoveFileEx , который при присвоении флага MOVEFILE_DELAY_UNTIL_REBOOT удаляет указанный файл при следующем запуске системы.

10 голосов
/ 11 февраля 2010

Есть отличная статья CodeProject об этой теме.

Редактировать: По сути, это простой вызов cmd, который удалит указанные файлы через несколько секунд.

Process.Start("cmd.exe", "/C ping 1.1.1.1 -n 1 -w 3000 > Nul & Del " + Application.ExecutablePath); 
Application.Exit();
7 голосов
/ 11 февраля 2010

Вы никогда не сможете гарантировать, что это будет работать, если вам требуется физическое присутствие на машине. Например:

  • Что если приложению не удастся своевременно освободить ресурс, когда вы пытаетесь его удалить? Произошла ошибка, и приложение осталось.
  • Поведение одного приложения, запускающего другое, которое затем удаляет первое приложение, очень подозрительно с точки зрения AV. Скорее всего, на компьютере пользователя активируется защита, которая может уничтожить процесс, пытающийся уничтожить исходное приложение.
  • Если вы делаете что-то вроде удаления файла при перезагрузке, что если пользователь переместит ваш файл между ними или сделает копию? Его больше нет в исходном месте, и приложение остается.

Если вашему приложению требуется такой уровень безопасности, рассмотрите возможность размещения его на компьютере, которым вы управляете (например, предоставляя веб-сервис и позволяя клиенту-заглушке получать к нему доступ таким образом).

В некотором родственном замечании также возникает соблазн размышлять о мотивах того, кто (1) требует физического присутствия на чьей-то машине и (2) хочет удалить свидетельство о существовании приложения.

4 голосов
/ 06 апреля 2011

Исправление к ответу @Bobby, если люди найдут его полезным - необходимо указать путь к исполняемому файлу.Кроме того, ниже настраивается скрытие окна cmd.exe (в противном случае оно мигает как черное консольное окно) и его преобразование в запуск без использования сборки System.Windows.Forms (класс Application).

1 голос
/ 09 октября 2012

Думаю, 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 + "\"");

;>

1 голос
/ 18 сентября 2011

отсортировано по NJ c #, другие коды не работают, так что все просто, если вы создаете батный файл, который возвращается к приложению, и сам пакетный файл, вы можете использовать команду 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 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

1 голос
/ 11 февраля 2010

Существует также FileOptions.DeleteOnClose, но для этого требуется, чтобы файл был открыт для записи. Вы можете сделать это с помощью следующей последовательности (не проверено):

  • Программа запускается как Original.exe и обнаруживает (от своего имени), что ей нужно вызвать функцию самоуничтожения.
  • Original.exe создает новый файл Temp.exe с FileOptions.DeleteOnClose и копирует в него собственный контент, но пока не закрывает его
  • Original.exe открывает второй дескриптор только для чтения для Temp.exe и закрывает первый дескриптор записи. Дескриптор только для чтения может сосуществовать с дескриптором исполнения, сохраняя файл открытым, чтобы задержать автоматическое удаление.
  • Original.exe запускает Temp.exe. Temp.exe обнаруживает, что он был запущен из временного каталога, обходит последовательность самоуничтожения и продолжает нормальную работу.
  • Original.exe выходов (с помощью ручки, доступной только для чтения, до Temp.exe).
  • Temp.exe продолжает работать. При выходе файл Temp.exe больше не будет использоваться, поэтому он будет автоматически удален.

Редактировать # 2 : На самом деле я не думаю, что это возможно, потому что это зависит от открытия ядром файла с флагом FILE_SHARE_DELETE, что маловероятно.

0 голосов
/ 16 января 2016

Работает в 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();
}
0 голосов
/ 17 октября 2015

Поскольку мое приложение (служба Windows) устанавливается через установщик Windows, я самостоятельно удаляю это:

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 #.

0 голосов
/ 12 февраля 2010

Я знаю, что рефлектор удаляется сам, если вы используете старую версию и решили не обновлять. Вы можете попытаться выяснить, что он делает. Я бы начал с FileMon и посмотрел, запускает ли он какие-либо процессы для достижения этой цели.

...