怎样删除自己(要彻底)(50分)

I

it80

Unregistered / Unconfirmed
GUEST, unregistred user!
我试了批处理 就是 在closeform时 建立一个 delself.bat文件来删除
在你直接点击文件执行时可以删除,但是如果是在 .lnk状态下执行只有50%的成功率
在卸载窗口里执行则一次成功也没有;怀疑是系统对象没有释放完毕;

那些卸载程序中删除自己并把父级目录删除是怎样做到的呢?
以前有个lovejiantao 的网好像有讲,现在找不到了
 
关注!up
 
Delphi 程序退出时删除自身的实现
这样取得的地址实际上是这个封装代码的,而这段代码又处于 UnmapViewOfMap 解除映像范围类,因此,到调用 DeleteFile 函数的时候就无法反问到这段代码了。

  解决的办法是,用GetProcAddress动态取得这几个API的地址。

  Delphi&CB代码如下
procedure DeleteSelf;
var pExitProcess: Pointer;
pDeleteFile: Pointer;
pUnmapViewOfFile: Pointer;
hModule: THANDLE;
cBuf:array[0..MAX_PATH]of Char;
begin
hModule := GetModuleHandle('kernel32');
if hModule <> 0 then
begin
pExitProcess := GetProcAddress(hModule, 'ExitProcess');
pDeleteFile := GetProcAddress(hModule, 'DeleteFileA');
pUnmapViewOfFile := GetProcAddress(hModule, 'UnmapViewOfFile');
end else
begin
pExitProcess := nil;
pDeleteFile := nil;
pUnmapViewOfFile := nil;
end;
hModule := GetModuleHandle(nil);
GetModuleFileName(hModule, cBuf, Sizeof(cBuf));
CloseHandle(THANDLE(4));
asm XOR EAX, EAX;
PUSH EAX;
PUSH EAX;
LEA EAX, cBuf;
PUSH EAX;
MOV EAX, pExitProcess;
PUSH EAX;
MOV EAX, hModule;
PUSH EAX;
MOV EAX, pDeleteFile;
PUSH EAX;
MOV EAX, pUnmapViewOfFile;
PUSH EAX; RET;
end;
end;
 
可以在delphi中删除自己,比用bat最好一些
 
在Windows NT中覆盖或删除正在使用的文件
这个函数就是<> MoveFileEx <>
这个函数充许我们对一个指定的文件或文件夹重命名. 但当我们指定它的dwFlags
参数为MOVEFILE_DELAY_UNTIL_REBOOT(只能用于Windows NT 4/2000)后, 它就将改写
注册表,在Windows重新启动后此文件就将被覆盖或删除.
用法:
MoveFileEx(ExistingFN, NewFN, MOVEFILE_REPLACE_EXISTING or
MOVEFILE_DELAY_UNTIL_REBOOT)
说明:
参数ExistingFN 指向一个以空字符结尾的字符串,此字符串即是待改变的文件或
文件夹。
参数NewFN 也是一个指向另一个空字符结尾的字符串,不同的是它表明的是新的文
件或文件夹的名称。
标志MOVEFILE_REPLACE_EXISTING 告诉函数如果ExistingFN所指的文件或文件夹已
经存在则覆盖它。如果NewFN指向nil,则 ExistingFN 所指的文件或文件夹就将被删除。
举例:
* 覆盖一个使用中的文件:
MoveFileEx('c:/winnt/system32/kernel32.dll',
'd:/winnt.bak/system32/kernel32.dll',
MOVEFILE_REPLACE_EXISTING or MOVEFILE_DELAY_UNTIL_REBOOT)
* 删除一个使用中的文件:
MoveFileEx('c:/winnt/system32/kernel32.dll', nil,
MOVEFILE_REPLACE_EXISTING or MOVEFILE_DELAY_UNTIL_REBOOT)
 
通通都不能用,啥也删不了
 
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
F:TextFile;
begin
AssignFile(F,'delself.bat');
Rewrite(F);{F为TextFile类型}
WriteLn(F,'del '+ExtractFileName(Application.ExeName));
WriteLn(F,'del %0');
CloseFile(F);
WinExec('delself.bat',SW_HIDE);
end;
 
program Hello;

{$APPTYPE CONSOLE}

uses
Windows,
SysUtils;

var //
szSrc, //
szDest : array[0..MAX_PATH] of char; //
szCmdLine : string;
hFile : THandle;
hProcess : THandle;
SI : TStartupInfo;
PI : TProcessInformation;
nTimes : DWord;
begin
if ParamCount = 0 then
begin
GetModuleFileName(0, szSrc, MAX_PATH);
GetTempPath(MAX_PATH, szDest);
GetTempFileName(szDest, 'Tmp', 0, szDest);
CopyFile(szSrc, szDest, FALSE); // 将当前可执行文件复制一个副本

hFile := CreateFile(szDest, // pointer to name of the file
0, // access (read-write) mode
FILE_SHARE_READ, // share mode
nil, // pointer to security attributes
OPEN_EXISTING, // how to create
FILE_FLAG_DELETE_ON_CLOSE, // file attributes
0); // handle to file with attributes to copy

hProcess := OpenProcess(SYNCHRONIZE, // access flag
TRUE, // handle inheritance flag
GetCurrentProcessId); // process identifier


szCmdLine := Format('%s %d "%s"', [szDest, hProcess, szSrc]); //格式化命令行参数

FillChar(SI, SizeOf(SI), 0);
SI.cb := SizeOf(SI);

CreateProcess(nil, // pointer to name of executable module
PChar(szCmdLine), // pointer to command line string
nil, // pointer to process security attributes
nil, // pointer to thread security attributes
TRUE, // handle inheritance flag
0, // creation flags
nil, // pointer to new environment block
nil, // pointer to current directory name
SI, // pointer to STARTUPINFO
PI); // pointer to PROCESS_INFORMATION

CloseHandle(hProcess);
CloseHandle(hFile);
end
else
begin
hProcess := THANDLE(StrToInt(ParamStr(1)));
WaitForSingleObject(hProcess, INFINITE); //等待主进程结束
CloseHandle(hProcess);
DeleteFile(ParamStr(2));
end;
end.
 
tseug 你这个方法,是把自己删除了,可是不是还留下一个副本吗?(野火烧不尽[:D])
 
程序说他想自杀
作者:万重 2001-8-18 原码(4.9K)
--------------------------------------------------

unit Unit1;

interface

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

type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation

{$R *.DFM}

procedure DeleteMe;
var
BatchFile: TextFile;
BatchFileName: string;
ProcessInfo: TProcessInformation;
StartUpInfo: TStartupInfo;
begin
BatchFileName := ExtractFilePath(ParamStr(0)) + '_deleteme.bat';

AssignFile(BatchFile, BatchFileName);
Rewrite(BatchFile);

Writeln(BatchFile, ':try');
Writeln(BatchFile, 'del "' + ParamStr(0) + '"');
Writeln(BatchFile,
'if exist "' + ParamStr(0) + '"' + ' goto try');
Writeln(BatchFile, 'del %0');
CloseFile(BatchFile);

FillChar(StartUpInfo, SizeOf(StartUpInfo), $00);
StartUpInfo.dwFlags := STARTF_USESHOWWINDOW;
StartUpInfo.wShowWindow := SW_HIDE;

if CreateProcess(nil, PChar(BatchFileName), nil, nil,
False, IDLE_PRIORITY_CLASS, nil, nil, StartUpInfo,
ProcessInfo) then
begin
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
end;
end;

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

end.
 
zw84611 的办法是对的,在 Bat 里面加循环,要是文件存在就不停地执行删除:)

 
这个办法太土了,能否成功我不知道,但是还留下一个_deleteme.bat
 
我记得windows有一个文件可以实现这样的功能,即在重启的时候执行一些操作,大部分的卸载程序都是这样做的。
但一时想不起是哪个了。
Thinking...
 
批处理是可以自己删除自己的
好象也就这个办法有效了
那个用汇编代码的在XP下就无效了。
 
to beta:
你没有见到那个是一个临时文件么? 当程序执行结束后它会被系统自动删除的...[8D][8D]
 
顶部