分享

程序自杀

 独孤求财 2012-03-20

程序自杀

时间:2011-5-26来源:yang 作者: peng点击: 32次

<<电脑商情报>>稿件    
                                         
                                                          安装与卸载之卸载篇---程序自杀  
                                                                                                                陈经韬  
   
              电脑用得久了,安装的软件乱七八糟,怎么办?一般我们会打开控制面版里的添加删除程序选项,选择相应的卸载选项就可以了。但如果我们能在自己的程序中增加一个删除功能来实现"自杀",则会令软件增色不少。  
            有点电脑常识的人都知道,在Windows下如果程序正在运行,那么是无法将其删除的,当然,也不是绝对不可以。CIH大家应该知道吧,它的核心有两个,一个就是取得Ring0级权限,然后就可以随便干想干的事(比如说修改正在运行的文件),而我们一般的程序是运行在Ring3级上的。顺便提一句---NT下没有Ring的概念,所以CIH对其无效。用Delphi内镶汇编也可以取得Ring0级权限,但如果我们的程序运行在NT或者Win2000下就没有效果了。在说句题外话,现在的编译器都很不错了,大多数程序员都编不出比编译器编译出的更理想的代码,象Delphi,如果将它的某些单元代码改用内镶汇编,在某些方面如字符串处理方面会提高5倍左右的效率,但NT不支持某些汇编代码,如果程序在NT下工作就会出错,怎么办?稳定第一!所以我们不用这个方法,而且,用这个方法有点杀鸡用牛刀的味道。  
        用过DOS的朋友应该还记得批处理文件吧,新建一个批处理文件a.bat,编辑其内容为:del   %0,然后运行它,怎么样?a.bat把自己删除掉了!!!好,我们就用它来进行程序的"自杀"!  
  找一个EXE可执行文件,比如说abc.exe,新建一个批处理文件a.bat,编辑其内容为:  
  :pp  
  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,‘:pp‘);  
  writeln(BatchFile,S1);  
  writeln(BatchFile,S2);  
  writeln(BatchFile,‘@del   %0‘);  
  closefile(BatchFile);  
  winexec(pchar(BatFilename),sw_hide);//隐藏窗口运行a.bat  
  application.Terminate;//退出程序  
  end;  
  那我们的事情是不是就完了?NO!上面的程序原理是对的,但如果你的程序是运行在系统目录下如Windows目录下或者Windows\System等目录下,除非你打开那个目录看着它删除,否则根本没法卸掉的。那怎么办?别急,我们请出一个函数CreateProcess,它的原型为:  
  BOOL   CreateProcess(  
  LPCTSTR   lpApplicationName,   //   pointer   to   name   of   executable   module    
  LPTSTR   lpCommandLine,   //   pointer   to   command   line   string  
  LPSECURITY_ATTRIBUTES   lpProcessAttributes,   //   pointer   to   process   security   attributes    
  LPSECURITY_ATTRIBUTES   lpThreadAttributes,   //   pointer   to   thread   security   attributes    
  BOOL   bInheritHandles,   //   handle   inheritance   flag    
  DWORD   dwCreationFlags,   //   creation   flags    
  LPVOID   lpEnvironment,   //   pointer   to   new   environment   block    
  LPCTSTR   lpCurrentDirectory,   //   pointer   to   current   directory   name    
  LPSTARTUPINFO   lpStartupInfo,   //   pointer   to   STARTUPINFO    
  LPPROCESS_INFORMATION   lpProcessInformation   //   pointer   to   PROCESS_INFORMATION    
  );  
  这个函数和OpenProcess、ReadProcessMemory、WriteProcessMemory使用可以用来读取和修改内存数据,常用的游戏修改器就是用它。由于这些不是本文的重点所以这里不作详细介绍,感兴趣的读者可自行翻阅Delphi自带的帮助文件。用CreateProcess函数创建一个进程就可以完美的完成我们的"程序自杀"了。  
  运行Delphi,新建一个工程,添加一个Button到窗体上,全部代码如下:  
   
  unit   Unit1;  
   
  interface  
   
  uses  
  Windows,   Messages,   SysUtils,   Classes,   Graphics,   Controls,   Forms,   Dialogs,  
  StdCtrls;  
  type  
  TForm1   =   class(TForm)  
  Button1:   TButton;  
  procedure   My_DeleteMe;   //自定义程序自杀过程  
  procedure   Button1Click(Sender:   TObject);  
  private  
  {   Private   declarations   }  
  public  
  {   Public   declarations   }  
  end;  
   
  var  
  Form1:   TForm1;  
   
  implementation  
   
  {$R   *.DFM}  
   
  procedure   TForm1.Button1Click(Sender:   TObject);  
  begin  
  My_DeleteMe;  
  end;  
  procedure   TForm1.My_DeleteMe;   //程序自杀  
  //-----------------------------------------------------------  
  function   GetShortName(sLongName:   string):   string;   //转换长文件名  
  var  
  sShortName:   string;  
  nShortNameLen:   integer;  
  begin  
  SetLength(sShortName,   MAX_PATH);  
  nShortNameLen   :=   GetShortPathName(PChar(sLongName),  
  PChar(sShortName),   MAX_PATH   -   1);  
  if   (0   =   nShortNameLen)   then  
  begin  
  //   handle   errors...  
  end;  
  SetLength(sShortName,   nShortNameLen);  
  Result   :=   sShortName;  
  end;  
  //-------------------------------------------------  
  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   "‘   +   GetShortName(ParamStr(0))   +   ‘"‘);  
  Writeln(BatchFile,   ‘if   exist   "‘   +   GetShortName(ParamStr(0))   +   ‘"‘   +   ‘   goto   try‘);  
  Writeln(BatchFile,   ‘del   %0‘);  
  Writeln(BatchFile,   ‘cls‘);  
  Writeln(BatchFile,   ‘exit‘);  
  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制作自己的安装程序。记得有一位著名的****说过:我从来不去找什么工具软件,需要的话就自己写一个。如果我们也持这种态度,则编程水平一定会越来越高。  
   
  ★作者:  
   
  陈经韬  
  Http:Lovejingtao.126.com    
  E-Mail:   Lovejingtao@21.cn.com  
     
                                                                  &copy;CopyRight   2000-2001      

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多