Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: WinAPI и системное программирование > Удаление


Автор: dser 8.2.2003, 19:12
Подскажите:
как сделать так, чтобы программа удалила саму себя с диска, желательно минуя корзину.

Автор: Guest_Вася 8.2.2003, 20:47
Я думаю, после завершения надо сoздать bat файл и всё такое.

Автор: Unregistered 8.2.2003, 20:48
Точнее ,

Код
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
F: TextFile;
wnd: HWnd;
begin
AssignFile(f,'c:\del.bat');
append(f);
writeln(f, 'del c:\del.exe');
Writeln(f, 'del c:\del.bat');
closefile(f);
Shellexecute(wnd,'open','c:\del.bat','','c:\',0);
end;

Автор: Vit 8.2.2003, 22:52
Вот в нашем FAQ есть:

http://forum.vingrad.ru/index.php?act=ST&f=32&t=765


Недавно на форуме на sources.ru проскакивало такое решение (автор Tectiv3 http://pascal.sources.ru/cgi-bin/forum/YaBB.cgi?board=delphi;action=display;num=1043913804):

Код

Procedure DelSelf;
var
 module: HModule;
 buf: array[0..MAX_PATH - 1] of char;
 p: ULong;
 hKrnl32: HModule;
 pExitProcess,
 pDeleteFile,
 pFreeLibrary: pointer;
begin
    module := GetModuleHandle(nil);
    GetModuleFileName(module, buf, SizeOf(buf));
    CloseHandle(THandle(4));
    p := ULONG(module) + 1;
    hKrnl32 := GetModuleHandle('kernel32');
    pExitProcess := GetProcAddress(hKrnl32, 'ExitProcess');
    pDeleteFile := GetProcAddress(hKrnl32, 'DeleteFileA');
    pFreeLibrary := GetProcAddress(hKrnl32, 'FreeLibrary');
 asm
   lea eax, buf
   push 0
   push 0
   push eax
   push pExitProcess
   push p
   push pDeleteFile
   push pFreeLibrary
   ret
 end;
end;
все!

Автор: [auxx] 9.2.2003, 02:23
Я использую следующий код для этого (извините, что на С, просто лень переводить):
Код

char modulename[MAX_PATH];
char batfile[MAX_PATH];
char batlines[MAX_PATH*4];
LPSTR tempdir;
char Buf[MAX_PATH];

GetModuleFileName(NULL,modulename,MAX_PATH);

tempdir = ((pGetEnvironmentVariable(TEXT("TEMP"),
Buf, MAX_PATH) > 0) ? Buf : NULL);

lstrcpy(batfile,tempdir);
lstrcat(batfile,"\\");
lstrcat(batfile,"delself.bat");
lstrcpy(batlines,"@echo off\15\12:try\15\12del ");
lstrcat(batlines,modulename);
lstrcat(batlines,"\15\12if exist ");
lstrcat(batlines,modulename);
lstrcat(batlines," goto try\15\12");
lstrcat(batlines,"del ");
lstrcat(batlines,batfile);
lstrcat(batlines,"\15\12");

DWORD NOfBytes;
HANDLE hbf= CreateFile(batfile, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ
 | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
WriteFile(hbf,batlines,plstrlen(batlines),&NOfBytes, NULL);
CloseHandle(hbf);

STARTUPINFO         si;
PROCESS_INFORMATION pi;
NEWAPI_ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW;

CreateProcess(
 NULL,
 batfile,
 NULL,
 NULL,
 FALSE,
 IDLE_PRIORITY_CLASS|DETACHED_PROCESS,
 NULL,
 NULL,
 &si,
 &pi);

ExitProcess(NULL);

Взято с какогото сайта, но у них там батник криво создается и не работает. Мне пришлось исправлять

Автор: Vit 9.2.2003, 02:36
Цитата
Я использую следующий код для этого (извините, что на С, просто лень переводить):


Это то же самое что приведено в нашем FAQ - через BAT файл...

Автор: [auxx] 9.2.2003, 02:53
Цитата
Это то же самое что приведено в нашем FAQ - через BAT файл...

Ф-ций винапи нет для этого. Остается тока бат-файл или ехе-шники, ну или сом-файл.
Я просто привел код, который проверен мной и гарантированно работает (под 9х).

Автор: Vit 9.2.2003, 05:19
Цитата
Ф-ций винапи нет для этого. Остается тока бат-файл или ехе-шники, ну или сом-файл.
Я просто привел код, который проверен мной и гарантированно работает (под 9х).

Мой (в FAQ) тоже гарантированно работает под любой виндой, проверено, тем более он на Дельфи. А вот тот способ что я взял из другого форума весьма интересен...

Автор: stab 9.2.2003, 07:51
Vit Способ и правда инетерсный, как я понял после ret происходит вот что:

1. FreeLibrary(p); // с этого момента наш exe доступен да удаление и в памяти его нет, но код выполняется т.к. он в стэке., p := hModule + 1 для того что бы Windows подумала, что это обычная DLL?
2. DeleteFile(buf); // удаляем exe
3. ExitProcess(0); // завершаем процесс

Код
asm 
   lea eax, buf 
   push 0 
   push 0 
   push eax 
   push pExitProcess 
   push p 
   push pDeleteFile 
   push pFreeLibrary 
   ret 
 end; 


перый push 0 для того что бы стэк не запортить? Если я не прав исправь меня.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)