Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Как осуществить удаление файла самим собой?


Страницы:   1 2

Дас Виндовс 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.


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо