2009-07-01 3 views
1

В мое приложение входит деинсталлятор. Все работает нормально, за исключением того, что я не могу найти способ удалить файл uninstaller.exe, когда все будет готово.Удалить загруженную в настоящий момент сборку

Я попытался скопировать текущую сборку exe в каталог temp, но файл-дескриптор исходного файла все еще заблокирован.

Любые идеи?

ответ

7

Для этого вам понадобится PInvoke. MoveFileEx имеет возможность запланировать удаление файла при следующей перезагрузке.

Если dwFlags определяет MOVEFILE_DELAY_UNTIL_REBOOT и lpNewFileName является NULL, MoveFileEx регистрирует файл lpExistingFileName быть удалены, когда система перезагружается.

Что-то вроде:

[return: MarshalAs (UnmanagedType.Bool)] 
[DllImport ("kernel32", CharSet = CharSet.Auto, SetLastError = true)] 
private static extern bool MoveFileEx (string lpExistingFileName, string lpNewFileName, int dwFlags); 

public static bool ScheduleDelete (string fileFullName) { 
    if (!File.Exists (fileFullName)) 
     throw new InvalidOperationException ("File does not exist."); 

    return MoveFileEx (fileFullName, null, 0x04); //MOVEFILE_DELAY_UNTIL_REBOOT = 0x04 
} 
+0

Спасибо! отлично работает ... никогда бы не подумал об этом , но есть ли способ удалить его прямо сейчас? Я знаю, что есть деинсталляторы, которые делают именно это! – Nissim

+0

Возможно, этот деинсталлятор выполняет какой-то другой движок, а не сам движок. Например, если у вас есть msi, он выполняется установщиком Windows, который фактически является другим приложением, поэтому он может удалить msi. Но в вашем случае это сам двигатель. Удаление заблокированного файла (любой файл, а не только EXE), возможно, будет файловой системой ... – Hemant

1

Было бы интересно, если бы вы опубликовали код того, как вы точно скопируете файл uninstaller.exe и смените выполнение на этот конкретный исполняемый файл.
Я думаю, unloading the application domain освободит файл-дескриптор.

+0

ничего фантазии, просто скопировать файл во временную директорию (используя File.Copy) , начиная его с помощью Prcess.Start и утилизации оригинального Что может помочь мне - это запустить exe без класса Process (больше в направлении PInvoke) – Nissim

0

Вы можете использовать «ЦМД» с задержкой:

internal static void ExitAndDelete() 
    { 
     var f = Application.ExecutablePath; 
     Process.Start(new ProcessStartInfo("CMD.exe", "/C timeout 2&del \"" + f + "\"") { WindowStyle = ProcessWindowStyle.Hidden }); 
    } 
Смежные вопросы