2015-03-31 3 views
4

Я работаю над приложением в C#, который делает следующие вещи:для Windows: Удаление EXE после выполнения

  1. Напишите EXE на диск
  2. Выполнить EXE через Process.Start()

Я теперь пытается убедиться, что EXE будет удален после его закрытия. Самый простой способ сделать это - установить параметр FileOptions.DeleteOnClose при создании EXE с использованием File.Create.

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

Есть ли способ сохранить «слабую ссылку» на EXE в моем приложении, которая не блокирует файл и позволяет его выполнять? В качестве альтернативы, есть ли способ разблокировать EXE для выполнения с открытым файловым дескриптором? Есть ли какие-либо другие очевидные решения, которые мне не хватает?

CLARIFICATION A: Мне известны другие методы удаления используемых файлов, которые в конечном итоге удалят файл (например, при перезагрузке). Однако я ищу способ удаления файла сразу после его запуска, который обрабатывается ОС (например, при запуске пакета, который сначала выполняет файл, а затем удаляет его, файл останется на диске, если пакетное задание будет завершено).

CLARIFICATION B: Чтобы объяснить большую картинку: приложение получает и расшифровывает исполняемый файл. После дешифрования файл должен быть выполнен. Тем не менее, я хочу, чтобы расшифрованная версия EXE не оставалась на диске. В идеале я также хочу, чтобы пользователи не копировали расшифрованный EXE. Однако, поскольку приложение дешифрования работает как один и тот же пользователь, это будет невозможно достичь по-настоящему безопасным способом, так как оба имеют одинаковые привилегии в системе.

+0

Я не согласен. Мое использование DeleteOnClose на самом деле происходит из статьи, связанной с лучшим ответом данного конкретного вопроса. MoveFileEx в конечном итоге удалит файл (т. Е. После перезагрузки), а не сразу после его закрытия. Поэтому я рассматриваю этот вопрос как конкретный вопрос о последующем вопросе к одному из ответов на вопрос, на который вы ссылаетесь. – 0x90

+0

То, чего вы пытаетесь достичь, не может быть выполнено с помощью 'Fileoptions.DeleteOnClose', потому что никакой программный файл не может быть выполнен, пока он открывается другим процессом для записи. (Я мог бы сказать вам, почему, но он ничего не делает с этой темой, и в этом комментарии недостаточно). Боюсь, вам нужно сделать это в три этапа: Write -> Start -> Delete. – mg30rg

+1

Хм. Это звучит неплохо. Что вы на самом деле пытаетесь сделать? – Luaan

ответ

8

Вы можете использовать Process.WaitForExit:

var process = Process.Start(processPath); 
process.WaitForExit(); 

// File.Delete(processPath); // Not strong enough (thanks to Binary Worrier) 
DeleteOrDie(processPath); // Will attempts anything to delete the file. 

Но это дает возможность скопировать ех от того, где вы записаны его.

Хорошим решением является его запуск из памяти.

Если ваша цель ехе программа CLR, вы можете использовать функцию Assembly.Load:

// read the file and put data in bin 
... 
Assembly a = Assembly.Load(bin); 
MethodInfo method = a.EntryPoint; 
if (method == null) throw new NoEntryPointException(); 
object o = a.CreateInstance(method.Name); 
method.Invoke(o, null); 

Более подробную информацию here.

Если вы хотите загрузить/выполнить любой ех в памяти, вы можете использовать Nebbett’s Shuttle подход, но вы должны code it in C/C++ и сделать вызов к нему из C#.

Также похоже, что Microsoft не нравится (проблемы с безопасностью), и я не думаю, что вы можете добиться этого только с C#. Хороший антивирус, вероятно, обнаружит его.

+0

+1: Обертка 'File.Delete' в цикле _catch/wait 10ms/retry_ может потребоваться, если есть задержка между завершением процесса и закрытием окна. –

+0

Ницца, это разумный ответ. Спасибо.Метод WaitForExit() оставил бы EXE на диске, если вызывающий процесс будет убит во время выполнения, но все же./К сожалению, мы ориентируемся не только на программы CLR, но и шаттл Nebbett может быть работоспособным. Я оставлю вопрос открытым дольше, чтобы узнать, что еще может произойти. – 0x90

2

В не очень хороший способ, но таким образом, что может дать вам то, что вы хотите, я предлагаю это решение:
(я использую Console Application с некоторыми входными аргументами для этого решения)

[1:] Написать функцию для проверки открытых процессов:

/// <summary> 
/// Check application is running by the name of its process ("processName"). 
/// </summary> 
static bool IsProcessOpen(string processName) 
{ 
    foreach (Processing.Process clsProcess in Processing.Process.GetProcesses()) 
    { 
     if (clsProcess.ProcessName.ToUpper().Contains(processName.ToUpper())) 
       return true; 
    } 
    return false; 
} 

[2:] Определить некоторые переменные:

static bool IamRunning = true; 
static int checkDuration = 1;  // in seconds 

[3:] Используйте тему для запуска цикла для проверки:

Thread t = new Thread(delegate() { 
    DateTime lastCheck = DateTime.MinValue; 
    while (IamRunning) 
    { 
     var now = DateTime.Now; 
     int dd = (now.Hour - lastCheck.Hour) * 3600 + (now.Minute - lastCheck.Minute) * 60 + now.Second - lastCheck.Second; 
     if (dd >= checkDuration) 
      if (!IsProcessOpen("ProcessName")) 
      { 
       delApplication(); // You have a function to delete ... 
       break; 
      } 
    } 
}); 
t.SetApartmentState(ApartmentState.STA); 
t.Start(); 

[4:] использовать цикл в конце программы:

while (t.ThreadState == ThreadState.Running) 
{ 
    // just wait. 
} 

Примечание: Это решение от Console Application на моем низком компьютере имеет 50% -е использование ЦП.

+0

У вас есть 50% (100% на одном из ваших двух CPU) использования, потому что у вас бесконечный цикл без 'Thread.Sleep' в Это. Более того, использование этого метода позволит избежать вашего разностного вычисления DateTime (плохо кодированного) (просто используйте '(DateTime.Now.Hour - lastCheck). Второй раз). И вы забудете сделать 'lastCheck = now;'. – Orace

+0

@Orace Спасибо, и я прошу [вопрос] (http://stackoverflow.com/q/29530946/4519059) об этом;). –

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