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

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

Самоудаление программы по нажатию на кнопку... [D7, XP, 2003]


Max.66RUS ©   (2008-01-02 13:05:00) 

Добрый день. Задача такая- в приложении есть кнопка на форме, по нажатию на которую, программа должна самоудалиться - пробовал использовать для этого процедуру с .bat файлом - почему-то не работает, хотя в приложениях без формы данная процедура работает на ура... Подскажите как переделать данный код чтобы он заработал в приложениях с формами. Вот код:

Procedure DELETE_APPLICATION;
Function GetTmpDir: String;
Var
PC: PChar;
Begin
PC:=StrAlloc(MAX_PATH+1);
GetTempPath(MAX_PATH, PC);
Result:=String(PC);
StrDispose(PC);
End;
Function GetTmpFileName(ext: String): String;
Var
PC: PChar;
Begin
PC:=StrAlloc(MAX_PATH+1);
GetTempFileName(PChar(GetTmpDir), 'uis', 0, PC);
Result:=String(PC);
Result:=ChangeFileExt(Result, ext);
StrDispose(PC);
End;
Var
BAT_FILE: TStringList;
BAT_FILE_NAME: String;
Begin
BAT_FILE_NAME:=GetTmpFileName('.bat');
FileSetAttr(ParamStr(0), 0);
BAT_FILE:=TStringList.Create;
With BAT_FILE do
Begin
Try
Add(':Label1');
Add('del "'+ParamStr(0)+'"');
Add('if Exist "'+ParamStr(0)+'" goto Label1');
Add('rmdir "'+ExtractFilePath(ParamStr(0))+'"');
Add('del '+BAT_FILE_NAME);
SaveToFile(BAT_FILE_NAME);
ChDir(GetTmpDir);
WinExec(PChar(BAT_FILE_NAME), SW_HIDE);
Finally
BAT_FILE.Free;
End;
Halt;
End;
End;


Заранее спасибо за ответ...


Max.66RUS   (2008-01-03 16:16:00) [1]

{RASkov}- спасибо огромное! Последний код работает на ура! Проблема решена.


easy   (2008-01-03 16:15:00) [2]

http://delphiworld.narod.ru/base/app_delete_itself.html
http://delphiworld.narod.ru/base/app_delete_itself2.html


{RASkov}   (2008-01-03 16:11:00) [3]

> Попробуй, я не пробывал:

Проверил - вроде бы работает.... по крайней мере у меня сработало как нужно :)


{RASkov}   (2008-01-03 15:59:00) [4]

> [9] Max.66RUS   (03.01.08 15:41)
> Код предложенный {RASkov} почему-то не работает

Странно.... я у себя проверял - работает.

Вот где-то в инете "спер" этот код. Попробуй, я не пробывал:

uses ShellAPI, ShlObj;

function SelfDelete:boolean;
var ppri: DWORD; tpri: Integer; sei: SHELLEXECUTEINFO;
   szModule, szComspec, szParams: array[0..MAX_PATH-1] of char;
begin
 Result:=false;
 if((GetModuleFileName(0,szModule,MAX_PATH)<>0) and
    (GetShortPathName(szModule,szModule,MAX_PATH)<>0) and
    (GetEnvironmentVariable('COMSPEC',szComspec,MAX_PATH)<>0)) then
 begin
   lstrcpy(szParams,'/c del ');
   lstrcat(szParams, szModule);
   lstrcat(szParams, ' > nul');

   sei.cbSize       := sizeof(sei);
   sei.Wnd          := 0;
   sei.lpVerb       := 'Open';
   sei.lpFile       := szComspec;
   sei.lpParameters := szParams;
   sei.lpDirectory  := nil;
   sei.nShow        := SW_HIDE;
   sei.fMask        := SEE_MASK_NOCLOSEPROCESS;

   ppri:=GetPriorityClass(GetCurrentProcess);
   tpri:=GetThreadPriority(GetCurrentThread);

   SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
   SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
   try
     if ShellExecuteEx(@sei) then
     begin
       SetPriorityClass(sei.hProcess,IDLE_PRIORITY_CLASS);
       SetProcessPriorityBoost(sei.hProcess,TRUE);

       SHChangeNotify(SHCNE_DELETE,SHCNF_PATH,@szModule,nil);

       result:=true;
     end;
   finally
     SetPriorityClass(GetCurrentProcess, ppri);
     SetThreadPriority(GetCurrentThread, tpri)
   end
 end
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
if not SelfDelete then ShowMessage('Error') else halt;
end;


Max.66RUS   (2008-01-03 15:41:00) [5]

В данный момент реализовал пока только один рабочий способ - сделал ещё одну программу, которая завершает и удаляет мою - включил её как ресурс в свою программу - при нажатии на кнопку она распаковывается на диск - запускается - завершает мою и удаляет её с диска - способ геморойный(увеличился на 20 Кб размер, геморой с компиляцией RES файла, включение его в программу, распаковка исполняемого файла на диск и т.д.) - и самый главный косяк - хоть моя программа и удалилась - но кто удалит ту программу которая удалила мою? Крайне нежелательно, чтобы на диске оставались какие-либо остатки от моей программы...

Код предложенный {RASkov}почему-то не работает - не пойму почему - при нажатии на кнопку программа закрывается, содается .bat файл и всё...(

У кого ещё какие есть мысли - как удалить программе саму себя и желательно без лишнего гемороя...


Виктор007   (2008-01-02 19:13:00) [6]

Вот код валялся у меня, не пробовал сам.
procedure OriginalChanger;
var szPathOrig, szPathClone: array [0..MAX_PATH] of char;
   szCmdLine: array [0..512] of char;
   hFile,hProcessOrig :THandle;
   si :TSTARTUPINFO;
   pi :TProcessInformation;
begin
     GetModuleFileName(Nil, szPathOrig, MAX_PATH);
     GetTempPath(MAX_PATH, szPathClone);
     GetTempFileName(szPathClone, PChar('Del'), 0, szPathClone);
     CopyFile(szPathOrig, szPathClone, FALSE);
     hfile := CreateFile(szPathClone, 0, FILE_SHARE_READ,
                         NIL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NIL);
     hProcessOrig := OpenProcess(SYNCHRONIZE, TRUE, GetCurrentProcessId);
     StrCopy(szCmdLine, PChar(Format('-CLONE %s %d "%s"',[szPathClone, hProcessOrig, szPathOrig])));
     ZeroMemory(@si, sizeof(si));
     si.cb := sizeof(si);
     CreateProcess(NIL, szCmdLine, NIL, NIL, TRUE, 0, NIL, NIL, si, pi);
     CloseHandle(hProcessOrig);
     CloseHandle(hfile);
end;

procedure CloneChanger(hProcessOrig :THandle; PathOrig:string);
begin
     WaitForSingleObject(hProcessOrig, INFINITE);
     CloseHandle(hProcessOrig);
     DeleteFile(PathOrig);
end;

begin
 if ParamStr(1) <>'-CLONE' then
 begin
   OriginalChanger;
   Exit;
 end
 else
   CloneChanger(StrToInt(ParamStr(2), StrToInt(ParamStr(3));
 Application.Init;
 ...
end.


{RASkov}   (2008-01-02 17:05:00) [7]

const BatFlNm = 'delapp.bat';
var F: TextFile; FullBatFlNm: String;
begin
 FullBatFlNm:=ExtractFilePath(Application.ExeName)+BatFlNm;
 AssignFile(F, FullBatFlNm);
 Rewrite(F);
 WriteLn(F, ':Start');
 WriteLn(F, 'del "'+Application.ExeName+'"');
 WriteLn(F, 'if exist "'+Application.ExeName+'" goto Start');
 WriteLn(F, 'del "'+FullBatFlNm+'"');
 CloseFile(F);
 WinExec(PChar(FullBatFlNm), SW_HIDE);
 Close;
end;


Bora_ru   (2008-01-02 16:30:00) [8]

сделай программу №2, задача которой завершить программу№1 и удалить ее с диска. Программу №2 заранее включи в №1 как ресурс. При нажатии кнопки, распаковывай №2 в windows\temp и запускай ее...


MetalFan   (2008-01-02 15:09:00) [9]

стандартными средствами запущенный исполняемый файл удалить нельзя


Max.66RUS   (2008-01-02 14:39:00) [10]

Да понятно, что это не "самоудаление" - но нужно чтобы исполняемый файл программы удалился по нажатию кнопки в этой программе - а каким способом - с .bat файлом или без - значения не имеет - если у кого есть подобный код - выложите его пожалуйста...


Сергей М.   (2008-01-02 13:39:00) [11]


>  программа должна самоудалиться - пробовал использовать
> для этого процедуру с .bat файлом


Это не "самоудаление".


Riply   (2008-01-02 13:30:00) [12]

> [0] Max.66RUS   (02.01.08 13:05)
пыталасьнонесумелапрочитатькод :)


Sergey Masloff   (2008-01-02 13:30:00) [13]

Цель такого действия? Вариантов решения - много, зависит от того для чего это нужно.


Наверх

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