![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Как осуществить удаление файла самим собой?
Дас Виндовс 45 © (2004-05-02 16:47:00)Как сделать так, чтобы файл сам себя удалил после завершения работы. Как это осуществляется в деинсталяторах?
Erik1 (2004-06-15 16:31:00) [1]У меня похожая задача, только достаточно переименовать фаил. Но это происходит на Terminal Server и загружен он во все Session. Как быть?
И еще, немогу понять когда он блокируется от переименования.
bolegator (2004-05-31 12:30:00) [2]Проверяется наличие на сервере новой версии.
Если есть, программа скачивает ее, выгружает себя из памяти, пишет на диск
на свое место новую версию экзешника, и уже на последнем издыхании,
перезапускает себя.
Последнее не всегда получается на WinXP.
Остальное работает исправно на любых windows.
procedure CheckNewVersion;
var t1,t2,k:integer; s,snew,sold:string;
var H:hwnd;
begin
if AppOptions.NoCheckUpgrade or (AppOptions.NewVerPath='') then exit;
t2:=FileAge(AppOptions.NewVerPath);
t1:=FileAge(ParamStr(0));
if (t2<>-1) and (t1<>-1) then begin
if FileDateToDateTime(t2)>FileDateToDateTime(t1) then begin
if not Warning('Обнаружена новая версия программы!'#10'Выполнить
обновление (рекомендуется)?') then exit;
s:=ExtractFileDir(ParamStr(0))+'\tmp.tmp';
if Windows.CopyFile(PChar(AppOptions.NewVerPath),PChar(s),False) then
begin
keybd_event(VK_LWIN,MapVirtualKey(VK_LWIN,0),0,0);
keybd_event(Ord('R'),MapVirtualKey(Ord('R'),0),0,0);
keybd_event(Ord('R'),MapVirtualKey(Ord('R'),0),KEYEVENTF_KEYUP,0);
keybd_event(VK_LWIN,MapVirtualKey(VK_LWIN,0),KEYEVENTF_KEYUP,0);
Application.ProcessMessages;
Sleep(100);
// ожидаем запуска окна
H:=0;
while True do begin
H:=FindWindow(nil,'Запуск программы');
if H<>0 then break
end;
hs:=0;
hsb:=0;
k:=0;
// ожидаем создания элементов окна
while True and (k<1000) do begin
{if not} EnumChildWindows(H,@EnumChildProc,0) {then break};
if (hs<>0) {and (hsb<>0)} then break;
inc(k)
end;
s:='"'+ParamStr(0)+'"';
for t1:=1 to ParamCount do s:=s+' '+ParamStr(t1);
if hs<>0 then SendMessage(hs,WM_SETTEXT,Length(s),integer(s))
else ErrorMsg('edit not found'{#10+s1+#10'END'});
SetForegroundWindow(H);
Windows.SetFocus(H);
SelfDeleteExeAndCopyNew;
ErrorMsg('Обновление не выполнено!')
end
end
else exit
end
else exit;
ErrorMsg('Не удалось обновить программу!')
end;
procedure SelfDeleteExeAndCopyNew;
var hModule,hKrnl32,hUser32:THandle; ExitCode:UINT;
szModuleName,szDirName,szTmpName,szNewName:array[0..MAX_PATH] of char;
pExitProcess,pDeleteFile,pFreeLibrary,pUnmapViewOfFile,pRenameFile,pKeybd_Ev
ent:pointer;
TmpName,NewName:string; kbReturn:integer;
begin
hModule:= GetModuleHandle(nil);
GetModuleFileName(hModule,szModuleName,sizeof(szModuleName));
StrPCopy(szDirName,ExtractFileDir(szModuleName));
hKrnl32:=GetModuleHandle('kernel32');
pExitProcess:=GetProcAddress(hKrnl32,'ExitProcess');
pDeleteFile:=GetProcAddress(hKrnl32,'DeleteFileA');
pFreeLibrary:=GetProcAddress(hKrnl32,'FreeLibrary');
pUnmapViewOfFile:=GetProcAddress(hKrnl32,'UnmapViewOfFile');
pRenameFile:=GetProcAddress(hKrnl32,'MoveFileA');
hUser32:=GetModuleHandle('user32');
pKeybd_Event:=GetProcAddress(hUser32,'keybd_event');
ExitCode:=System.ExitCode;
TmpName:=ExtractFileDir(szModuleName)+'\tmp.tmp';
NewName:=szModuleName;
StrPCopy(szTmpName,TmpName);
StrPCopy(szNewName,NewName);
kbReturn:=MapVirtualKey(VK_RETURN,0);
SetCurrentDirectory(pchar(ExtractFileDir(szDirName)));
if ($80000000 and GetVersion())<>0 then // Win95,98,Me
asm
lea eax,szModuleName
lea ecx,szTmpName
lea edx,szNewName
push ExitCode
push 0
// keybd_event(VK_RETURN,MapVirtualKey(VK_RETURN,0),KEYEVENTF_KEYUP,0);
push 0
push KEYEVENTF_KEYUP
push kbReturn
push VK_RETURN
push pExitProcess
// keybd_event(VK_RETURN,MapVirtualKey(VK_RETURN,0),0,0);
push 0
push 0
push kbReturn
push VK_RETURN
push pKeybd_Event
push edx
push ecx
push pKeybd_Event
push eax
push pRenameFile
push hModule
push pDeleteFile
push pFreeLibrary
ret
end
else begin
// Win2000,XP
CloseHandle(THANDLE(4));
asm
lea eax,szModuleName
lea ecx,szTmpName
lea edx,szNewName
push ExitCode
push 0
// keybd_event(VK_RETURN,MapVirtualKey(VK_RETURN,0),KEYEVENTF_KEYUP,0);
push 0
push KEYEVENTF_KEYUP
push kbReturn
push VK_RETURN
push pExitProcess
// keybd_event(VK_RETURN,MapVirtualKey(VK_RETURN,0),0,0);
push 0
push 0
push kbReturn
push VK_RETURN
push pKeybd_Event
push edx
push ecx
push pKeybd_Event
push eax
push pRenameFile
push hModule
push pDeleteFile
push pUnmapViewOfFile
ret
end
end
end;
var hs,hsb:hWnd;
function EnumChildProc(h:hWnd; lParam:longint):BOOL; stdcall;
var lpBuffer:PChar; p,p1:array[0..256] of char;
begin
Result:=True;
if h=0 then exit;
lpBuffer:=@p1;
if GetClassName(h,lpBuffer,255)>0 then begin
if UpperCase(StrPas(lpBuffer))='EDIT' then hs:=h
else
if (StrPas(lpBuffer)='Button') and (hsb=0) then begin
GetWindowText(h,p,255);
if PChar(@p)='ОК' then hsb:=h;
end;
end;
Result:=True;
end;
Type
SHRunDialogProc = function (wnd : HWND; Unknown1:integer; Unknown2 :
Pointer; szTitle : PChar; szPrompt : PChar; uiFlages :
integer) : DWORD; stdcall;
var
SHRunDialog : SHRunDialogProc;
var
ShellHandle: THandle;
mamont (2004-05-23 17:50:00) [3]Программа program.exe создает бат файл, например kill.bat.
В файл записывает:
del path/program.exe
del kill.bat
Запускает kill.bat и завершается. Проверено, работает.
Black Krok (2004-05-20 15:05:00) [4]Может я что-то не то посоветую, но мой деинсталлятор при запуске переписывал себя самого во временный каталог виндов. Запускал сам себя оттуда с нек. параметром и заканчивал работу. А тот, запущенный с параметром сносил все, до чего мог дотянуться, а выходя завещал системе себя удалить при очередном перезапуске.
На Win2000 это:
MoveFileEx(PChar('Имя файла'),nil,MOVEFILE_DELAY_UNTIL_REBOOT);
На win98:
В файл
NameSystemDir+'\..\WININIT.INI'
пишется строка(если его нет - создать)
[rename]
NUL='Имя файла'
Если Вы не боитесь напугать пользователя предложением перезагрузки - не заморачивайтесь с копирование и перезапуском, а завещайте системе удалить свой файл и перезагружайтесь.
Dimaxx (2004-05-12 21:34:00) [5]Шишь! В ХРюше не удаляет, но выходит из нее...
avakss (2004-05-12 18:39:00) [6]>yanis © (12.05.04 11:33) [16]
>здаётся мне последний приведённый код взят из фака!!! Хотя бы >ссылочку на оригинал оставил.
тем не менее я показал прогу рабочую, а не трепался на разные темы
Kerk (2004-05-12 11:43:00) [7]
> yanis © (12.05.04 11:33) [16]
Выше я дал ссылку, где обсуждаются разные способы удаления самого себя в разных ОС.
yanis (2004-05-12 11:33:00) [8]здаётся мне последний приведённый код взят из фака!!! Хотя бы ссылочку на оригинал оставил.
avakss (2004-05-12 10:20:00) [9]Удаляет запущенную прогу--проверено на Win2000
procedure DeleteSelf;
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;
Dimaxx (2004-05-09 21:34:00) [10]А поконкретнее и на паскале? :-)
Kerk (2004-05-05 09:49:00) [11]http://www.bugtraq.ru/cgi-bin/forum.mcgi?type=sb&b=2&m=102104
Gero (2004-05-04 20:41:00) [12]
> Скрипты тоже сами себя удалять могут
См. [7]
AlexZ_CRC (2004-05-04 20:21:00) [13]>>[i]Сам себя файл удалить не может.[/i]
Неправда. Прога NJWIN.exe - пример самоудаления.
Скрипты тоже сами себя удалять могут. (Сразу после исполнения)
Mim1 (2004-05-03 17:36:00) [14]
var DeskTop : string;
StartDir : string;
GameDir : string;
DelFiles : TStringList;
DelFolders : TStringList;
trs : TResourceStream;
i : integer;
buf : array [1..max_path] of char;
fn : string;
begin
....
// self destructiong
GetTempPath(SizeOf(Buf),@Buf);
randomize;
repeat
fn := IncludeTrailingBackslash(copy(Buf,1,lstrlen(@Buf))) +
'eiu_'+IntToStr(random(99999))+'.bat';
until Not FileExists(fn);
with TStringList.Create do
begin
add(':del');
add(format('del "%s"',[application.exename]));
add(format('IF NOT EXIST "%s" goto exit',[application.exename]));
add('goto del');
add(':exit');
add(Format('rd "%s"',[GameDir]));
add(Format('del "%s"',[fn]));
SaveToFile(fn);
free;
end;
WinExec(pchar(fn),SW_HIDE);
DelFiles.Free;
DelFolders.Free;
Application.MessageBox('"даление завершено','"даление игры',mb_ok or MB_ICONINFORMATION);
UnInstallComplete := true;
end;
end;
default (2004-05-02 21:57:00) [15]кстати можно сделать так, чтоб файл удалился после выгрузки его на диск через bat-файл
uny (2004-05-02 21:38:00) [16]есть "виртуальные" диски - оперативную память используют.
разве нельзя создать такой диск, закачать туда exe, запустить, и всё удалить с реального диска
Gero (2004-05-02 21:32:00) [17]
> Ни один файл не может удалять, возможность удаления обладают
> или программы или скрипты
Только программы.
Скрипт-то тоже программа выполняет.
Yanis (2004-05-02 21:21:00) [18]> после перезагрузки при использовании bat-файлов или реестра
Не обязательно после перезагрузки. bat файл может удалить себя сам...
...значит ничего не мешает, сделать из программы(т.е. программно) текстовый файл с расширением *.bat, а в нём написать команды dos, которые будут удалять программу(вашу или нет - это уже другой вопрос).
SammIk (2004-05-02 20:15:00) [19]rundll.exe тебе поможет))
дZен скоро наступит
Юрий Зотов (2004-05-02 17:17:00) [20]> Дас Виндовс 45 (02.05.04 16:47)
> Как это осуществляется в деинсталяторах?
См. MoveFileEx и флаг MOVEFILE_DELAY_UNTIL_REBOOT.