Как удалить самого себя?

Есть exe. Он запущен. Задача удалить его с диска в то время, когда он запущен. И сделать должен он сам. Как бы это сделать ?
Вкратце возможны решения:
1. Через MoveFileEx
2. Через WININT.INI
3. Через трюк с bat-файлом.

Хе хе. А для чего, по вашему, всякие ре/де/пере инсталляторы перезагрузку просят? Там не bat, там WININIT.INI. Ну вообще-то под NT я прокатывал вариант - открыть свой файл на чтение с DELETE_ON_CLOSE - вообще-то работает, но какие-то там завитухи промелькивали. Стабильность как-то с трудом достигалась. Ну вот - специально поднял исходник:

SECURITY_ATTRIBUTES sa = {sizeof(sa), NULL, TRUE };
CreateFile(exename, 0, FILE_SHARE_READ, &sa,
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL|FILE_FLAG_DELETE_ON_CLOSE, NULL);


и _потом_ запустить exename - себя же. И там потом ещё между ними двумя синхронизация делается: 1й должен понять что 2й запустился, и завершиться. 2й должен ждать когда 1й завершится.
при таком раскладе - железно работает. Но это всё - только про NT. А W9X - "подождите, пока система выполнит обновление файлов" (WININIT)

Трюк с bat файлом - проверял, работает Делаешь такой bat файл:

@echo off
:Repeat
del [сюда имя своего exe файла]
if exist [опять имя exe файла] goto Repeat
del %0


А в программе перед выходом пишешь
CreateProcess(...,IDLE_PRIORITY_CLASS,...) SetThreadPriority(pinf.hThread,THREAD_PRIORITY_IDLE)

Насчет бат файла, есть в виндах 9х (насчет NT руки не дошли проверить) файл такой autostart.bat, по моему, так вот он и выполняется перед запуском GUI, это кады пишется "Видовз производит обновление файлов подождите..." Так вот через него деинсталяторы и стирают то, что не могут стереть сразу (поверял) Естественно для этого компьютер должен быть перезагружен.

Это сообщение появляется, когда что-то записано в wininit.ini. И файл этот обрабатывается прогрммой wininit.exe, которая кстати длинных имен не понимает. И помимо стирания ей можно еще и файлики копировать, те которые после запуска будут сразу-же загружены, например mfc42.dll А в NT это делается командой MoveFileEx с установленным флагом MOVEFILE_DELAY_UNTIL_REBOOT. При этом данные заносятся в registry.

http://microsoft.com/msj/0198/win320198.htm
Вот мой вариант:
main(){
...
CreateProcess("start.exe","start.exe /w /m %%COMSPEC%% /c del filename.exe",
NULL,NULL,TRUE,CREATE_NEW_PROCESS_GROUP|DETACHED_PROCESS| IDLE_PRIORITY_CLASS,
NULL,CurrentPath,&CurrentEnv,&TecEnv);
return 0;
}



TopList Rambler's Top100