给你转一篇文章,挺有启发的
以下为转的:
程序自杀
电脑用得久了,安装的软件乱七八糟,怎么办?一般我们会打开控制面板里的添加删除程序选项,选择相应的卸载选项就可以了。但如果我们能在自己的程序中增加一个删除功能来实现“自杀”,则会令软件增色不少。
有点电脑常识的人都知道,在Windows下如果程序正在运行,那么是无法将其删除的,当然,也不是绝对不可以。CIH大家应该知道吧,它的核心有两个,一个就是取得Ring0级权限,然后就可以随便干想干的事(比如说修改正在运行的文件),而我们一般的程序是运行在Ring3级上的。顺便提一句——NT下没有Ring的概念,所以CIH对其无效。用Delphi内镶汇编也可以取得Ring0级权限,但如果我们的程序运行在NT或者Win2000下就没有效果了。在说句题外话,现在的编译器都很不错了,大多数程序员都编不出比编译器编译出的更理想的代码,象Delphi,如果将它的某些单元代码改用内镶汇编,在某些方面如字符串处理方面会提高50倍左右的效率,但NT不支持某些汇编代码,如果程序在NT下工作就会出错,怎么办?稳定第一!所以我们不用这个方法,而且,用这个方法有点杀鸡用牛刀的味道。
用过DOS的朋友应该还记得批处理文件吧,新建一个批处理文件a.bat,编辑其内容为:del %0,然后运行它,怎么样?a.bat把自己删除掉了!好,我们就用它来进行程序的“自杀”!
找一个EXE可执行文件,比如说abc.exe,新建一个批处理文件a.bat,编辑其内容为:
p
del abc.exe
if exist abc.exe goto pp
del %0
先运行abc.exe,再运行a.bat,然后将abc.exe退出,你会发现a.exe和a.bat都没有了!按照这个思路,我们可以在程序中根据文件名称写一个批处理,将上面的abc.exe换成自己的EXE文件名就可以了。运行Delphi,新建一个工程,添加一个Button到窗体上,点击Button,写下如下代码:
procedure TForm1.Button1Click(Sender:TObject);
var Selfname,BatFilename,s1,s2:string;
BatchFile:TextFile;
begin
Selfname:=Extractfilename(application.exename); //取EXE文件自己的名称
BatFilename:=ExtractFilePath(Application.ExeName)+a.bat; //批处理文件名称
S1:=@del+Selfname;
S2:=if exist+Selfname+goto pp;
assignfile(BatchFile,BatFilename);
rewrite(BatchFile);
writeln(BatchFile,
p);
writeln(BatchFile,S1);
writeln(BatchFile,S2);
writeln(BatchFile,@del %0);
closefile(BatchFile);
winexec(pchar(BatFilename),sw_hide); //隐藏窗口运行a.bat
application.Terminate; //退出程序
end;
那我们的事情是不是就完了?NO!上面的程序原理是对的,但如果你的程序是运行在系统目录下如Windows目录下或者WindowsSystem等目录下,除非你打开那个目录看着它删除,否则根本没法卸掉的。这可能是因为Windows对系统目录有保护功能,那怎么办?别急,我们请出一个函数CreateProcess,感兴趣的读者可自行翻阅Delphi的帮助文件来查看它的原型。这个函数和OpenProcess、ReadProcessMemory、WriteProcessMemory使用可以用来读取和修改内存数据,常用的游戏修改器就是用它。(未完待续)
(湖北 陈经韬)
(接上期)
用CreateProcess函数创建一个进程就可以完美的完成我们的“程序自杀”了,代码如下:
procedure TForm1.My_DeleteMe;
var
BatchFile:TextFile;
BatchFileName:string;
ProcessInfo:TProcessInformation;
StartUpInfo:TStartupInfo;
begin
BatchFileName:=ExtractFilePath(ParamStr(0))+$$a.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"+BatchFileName+"
;
Writeln(BatchFile,cls);
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;
Application.Terminate;
end;
end.
补充:1.上面的批处理的del %0等同于del a.bat,用del a.bat则批处理文件必须为a.bat,用del %0则可以随意;
2.程序在Pwin98+Delphi5、Win2000+Delphi5下运行通过。
本文的标题为《安装与卸载之卸载篇——程序自杀》,下次将介绍如何用Delphi制作自己的安装程序。记得有一位著名的黑客说过:我从来不去找什么工具软件,需要的话就自己写一个。如果我们也持这种态度,则编程水平一定会越来越高。(湖北 陈经韬)