Array
(
)

Apagar o proprio exe na saida

Marcosrodias
   - 12 ago 2004

OIIIIIIIIIIIII

Como faço para apagar o executável na saida dele. Ele só deve ser executado uma vez e na sua finalização tem de ser apagado automaticamente.

Abracos

Marcos Roberto


Paullus
   - 12 ago 2004

Meu amigo...

Até onde eu sei não tem como. Porque o executável vai estar sendo executado e o sistema operacional não permite.

O que se pode fazer é criar um arquivozinho .BAT e colocar no RunOnce do registro (e sinceramente eu nem sei se vai funcionar).


Marcosrodias
   - 12 ago 2004

Ola colega

Eu recebi um dia desses essa rotina. Mas achei que nao ia precisar e apaguei o email que continha essa função.

Agora to no aporte

Um Abarco

Marcos Roberto


Tatuweb
   - 12 ago 2004

Não é muito complicado. A rotina abaixo resolve o seu problema:

#Código

procedure DeleteSelf;
var
hModule:THandle;
szModuleName: array[0..MAX_PATH] of char;
hKrnl32: THandle;
pExitProcess, pDeleteFile, pFreeLibrary, pUnmapViewOfFile: Pointer;
ExitCode: UINT;
begin
hModule:= GetModuleHandle (nil);
GetModuleFileName (hModule, szModuleName, SizeOf (szModuleName));
hKrnl32 := GetModuleHandle (´kernel32´);
pExitProcess := GetProcAddress (hKrnl32,´ExitProcess´);
pDeleteFile := GetProcAddress (hKrnl32,´DeleteFileA´);
pFreeLibrary := GetProcAddress (hKrnl32,´FreeLibrary´);
pUnmapViewOfFile := GetProcAddress (hKrnl32,´UnmapViewOfFile´);
ExitCode := system.ExitCode;

if ($80000000 and GetVersion) <> 0 then
asm
LEA EAX, szModuleName
PUSH ExitCode
PUSH 0
PUSH EAX
PUSH pExitProcess
PUSH hModule
PUSH pDeleteFile
PUSH pFreeLibrary
RET
end else
begin
CloseHandle (THANDLE (4));
asm
LEA EAX, szModuleName
PUSH ExitCode
PUSH 0
PUSH EAX
PUSH pExitProcess
PUSH hModule
PUSH pDeleteFile
PUSH pUnmapViewOfFile
RET
end;
end;
end;


Como o Xp tem algumas ´frescuras´ eu não sei se vai funcionar nesse sistema. A princípio deve funfar no XP também mas eu não testei nele. Nos outros Windows funciona sem problemas.

Para usar basta chamar a rotina em qualquer lugar do programa, por exemplo, ao clicar num botão:

#Código
procedure TForm1.Button1Click(Sender: TObject);
begin
DeleteSelf;
end;

Para que a rotina funcione vc deve testar fora do ambiente delphi, isto é, vc deve ir lá na pasta onde o exe foi gerado de clicar nele. Se der F9 para testar não vai funcionar pois o Delphi não vai permitir que o arquivo seja deletado.


Marcosrodias
   - 12 ago 2004

Ola amigao

É no xp nao fuicionou nao mas ja deu para quebrar o galho.

Muito obrigado

Marcos Roberto - Salvador/ba


Demolitor
   - 13 ago 2004

Cara, este eh o codigo que peguei na net que cria um arquivo de LOTE (BAT) que deleta o executavel...

unit Unit_AutoDelecao;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;

type
TDriveType = (dtUnknown, dtNoDrive, dtFloppy, dtFixed, dtNetwork, dtCDROM, dtRAM);
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

function GetTmpDir: string; // Get the windows temporary directory
var
pc: PChar;
begin
pc := StrAlloc(MAX_PATH + 1);
GetTempPath(MAX_PATH, pc);
Result := string(pc);
StrDispose(pc);
end;

procedure DelExe; // procedure to delete the current program
function GetTmpFileName(ext: string): string;
var
pc: PChar;
begin
pc := StrAlloc(MAX_PATH + 1);
GetTempFileName(PChar(GetTmpDir), ´EZC´, 0, pc);
Result := string(pc);
Result := ChangeFileExt(Result, ext);
StrDispose(pc);
end;
var
batchfile: TStringList;
batchname: string;
begin
if (TDRiveType(GetDriveType(PChar(´C:\´))) = dtFloppy) or (TDRiveType(GetDriveType(PChar(´C:\´))) = dtFixed) then
begin
batchname := GetTmpFileName(´.bat´);
FileSetAttr(ParamStr(0), 0);
batchfile := TStringList.Create;
with batchfile do
begin
try
Add(´:Label1´);
Add(´del ´´ + ParamStr(0) + ´´´);
Add(´if Exist ´´ + ParamStr(0) + ´´ goto Label1´);
Add(´rmdir ´´ + ExtractFilePath(ParamStr(0)) + ´´´);
Add(´del ´´ + GetTmpDir + ExtractFileName(ParamStr(0)) + ´´´);
Add(´del ´ + batchname);
SaveToFile(batchname);
ChDir(GetTmpDir);
WinExec(PChar(batchname), SW_HIDE);
finally
batchfile.Free;
end;
Halt;
end;
end //else with Owner as TForm do Close;
end;


procedure TForm1.Button1Click(Sender: TObject);
begin
DelExe;
end;

end.
Espero ter ajudado...
Falow.


Marcosrodias
   - 13 ago 2004

Obrigado pela coloaboração tambem. Tai uma rotina interessante

Um abraco

Marcos Roberto


Paullus
   - 13 ago 2004

Eu falei que um BAT dava conta do recado. :wink:
Agora muito interessante a rotina em Assembly do TatuWeb. Só que, como eu tinha falado, até onde eu sei usando Object Pascal não tem como. :(