我做了一个安装程序,文件夹d:\my program里面有一个安装文件setup.exe,还有一个删除文件uninstall.exe.我要双击uninstall.exe后,删除程序后最终还要把本身uninstall.exe文件删除,怎么办?不解,苦恼中.....

解决方案 »

  1.   

    建立一个批处理文件  del.bat 内容del uninstall.exe
    del %0在你的uninstall.exe退出的时候执行  winexec('del.bat', SW_HIDE );这样就可以把自己也删掉了。
      

  2.   

    在进程退出前,用fwrite等方法输出一个.BAT文件,在里面写几句DEL,然后WINEXEC一下这个BAT文件即可
      

  3.   

    收集到的资料:程序的自删除已经不是什么新鲜的话题了,它广泛运用于木马、病毒中。试想想,当你的程序还在运行中(通常是完成了驻留、感染模块),它就自动地把自己从磁盘中删掉,这样一来,就做到了神不知鬼不觉,呵呵,是不是很cool呢?自删除(Self Deleting)最早的方法是由 Gary Nebbett 大虾写的,太经典了,不能不提。程序如下:#include "windows.h"int main(int argc, char *argv[])
    {
        char    buf[MAX_PATH];
        HMODULE module;
        
        module = GetModuleHandle(0);
        GetModuleFileName(module, buf, MAX_PATH);
        CloseHandle((HANDLE)4);
        
        __asm 
        {
          lea     eax, buf
          push    0
          push    0
          push    eax
          push    ExitProcess
          push    module
          push    DeleteFile
          push    UnmapViewOfFile
          ret
        }
         
        return 0;
    } 试试编译它,运行。怎么样?从你的眼皮底下消失了吧?是不是很神奇?Gary Nebbett 钻了系统的一个漏洞,他的程序是关闭了 exe 文件的 IMAGE(硬编码为4),然后用 UnmapViewOfFile 解除了 exe 文件在内存中的映象,接着通过堆栈传递当前程序的 Handle 给 DeleteFile() ,实现了程序的自删除。Gary Nebbett 果然不愧为 WIN 系统下顶尖的底层高手。那么是否还有其他的方法实现程序的自删除呢?答案是肯定的。在 Win9x/ME 下,还可以利用 WININIT.INI 的一些特性。在 WININIT.INI 文件里面有一个节 [Rename] ,只要在里面写入要 “Nul=要删除的文件”,那么下次系统重新启动的时候,该文件就会被自动删除了。以下是一个例子:[Rename]
    NUL=c:\SelfDelete.exe 利用这个特性,我们就可以在程序中对这个 ini 文件进行操作。值得注意的是,当需要自删除的文件多于一个的时候,就不能使用 WritePrivateProfileString 来实现,因为这个 API 会阻止多于一个“NUL=”这样的入口在同一个节里面出现,所以最好还是自己手动实现。第三种方法是利用批处理文件。先让我们做一个试验:创建一个 a.bat ,给它写入以下内容:del %0.bat 现在运行它吧,屏幕一闪而过,最后留下一串字符:“The batch file cannot be found”。这时候它已经从你的硬盘中消失了。这说明,批处理文件是可以删除自己的,于是我们可以把这个小技巧运用在自己的程序当中::Repeat
    del "C:\MYDIR\SelfDelete.exe"
    if exist "SelfDelete.exe" goto Repeat
    rmdir "C:\MYDIR"
    del "\DelUS.bat" 它会重复不断地搜索是否有 SelfDelete.exe 这个文件,直到删除了它为止;当删除完毕后,这个批处理文件就会把自己删除。
    (注:本方法可以支持所有的 Windows 版本,即 Win9x/Me/NT/2000/XP)用批处理文件的方法有一个缺陷,就是会突然弹出一个 DOS 窗,冷不防的吓人一跳,不过据我所知这是目前唯一可以在 WinXP 下起作用的方法。当然,最理想的方法是用 Gary Nebbett 的那种,不过它的缺陷是没法在 WinXP 下起作用。(注:Gary Nebbett 的方法,hume已经给出了例子,所以我就不重复了,请到他的网站 http://humeasm.yeah.net 下载。)
    以上的方法都是前辈高人的研究总结,可不是我原创的,不过最后我给出一个 Win32ASM 例子,演示一下用批处理文件删除程序自身的方法。
    ;******************************************************
    ;程序名称:程序自删除示例,适用于Win9x/WinMe/Win2000/WinXP
    ;作者:罗聪
    ;日期:2002-10-23
    ;出处:http://www.luocong.com(老罗的缤纷天地)
    ;注意事项:如欲转载,请保持本程序的完整,并注明:
    ;转载自“老罗的缤纷天地”(http://www.luocong.com)
    ;******************************************************.386
    .model flat, stdcall
    option casemap:noneinclude \masm32\include\windows.inc
    include \masm32\include\kernel32.inc
    include \masm32\include\shell32.inc
    include \masm32\include\user32.inc
    includelib \masm32\lib\user32.lib
    includelib \masm32\lib\kernel32.lib
    includelib \masm32\lib\shell32.libDeleteExecutableBF        PROTO.code
    main:
        invoke DeleteExecutableBF
        invoke ExitProcess, NULL;********************************************
    ; 模块功能:用批处理文件删除自身
    ; 入口参数:无
    ; 出口参数:无
    ;********************************************
    DeleteExecutableBF    proc
        LOCAL    hFile                :DWORD
        LOCAL    len                  :DWORD
        LOCAL    hHeap                :DWORD    
        LOCAL    pszUnsetupPathname   :DWORD
        LOCAL    pszUnsetupPath       :DWORD
        LOCAL    pszBatFilePathname   :DWORD
        LOCAL    pBatFile             :DWORD    jmp nextcode    szBatFileName                 BYTE    "DelUS.bat", 0
        szOpen                        BYTE    "open", 0
        szBKSlash                     BYTE    "\", 0
        L1                            BYTE    ":Repeat", 13, 10, 0
        L2A                           BYTE    "del """, 0
        L2B                           BYTE    """", 0
        L3A                           BYTE    13, 10, "if exist """, 0
        L3B                           BYTE    """ goto Repeat", 13, 10, 0
        L4                            BYTE    "rmdir """, 0
        L5                            BYTE    """",13, 10, "del """, 0
        L6                            BYTE    """",13, 10, 0
        
    nextcode:
        ; 为字符串分配堆:
        invoke GetProcessHeap
        mov hHeap, eax
        invoke HeapAlloc, hHeap, NULL, 4 * MAX_PATH + 1000
        mov pszUnsetupPath, eax
        add eax, MAX_PATH
        mov pszUnsetupPath, eax
        add eax, MAX_PATH
        mov pszUnsetupPathname, eax 
        add eax, MAX_PATH    
        mov pszBatFilePathname, eax 
        add eax, MAX_PATH        
        mov pBatFile, eax    ; 创建一个批处理文件,用于删除我们的exe文件。当exe文件被删除后,这个批处理文件会自动删除自己,以及它所在的目录。    ; 得到 temp 目录的路径:
        invoke GetTempPath, MAX_PATH, pszBatFilePathname    invoke lstrcat, pszBatFilePathname, addr szBatFileName
        invoke CreateFile, pszBatFilePathname, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
                       FILE_ATTRIBUTE_NORMAL or FILE_FLAG_SEQUENTIAL_SCAN, NULL
        mov hFile, eax
        .if (hFile != INVALID_HANDLE_VALUE)     ; 得到我们的 exe 文件的全路径(包括文件名):
        invoke GetModuleFileName, NULL, pszUnsetupPathname, MAX_PATH    ; 得到我们的 exe 文件的路径(不包括文件名):
        invoke lstrcpy, pszUnsetupPath, pszUnsetupPathname    ; 找到路径最后的 ’\’ 并把它改成0
        mov edx, pszUnsetupPath
        mov ecx, edx
        .repeat
            mov al, byte ptr [edx]
            .if al == 92 ; "\"
                mov ecx, edx
            .endif
           inc edx
        .until al == 0
            mov byte ptr [ecx+1], 0           ; Bat 文件的内容:
            ; :Repeat
            ; del "C:\Win95ADG\DelSelf.exe"
            ; if exist "DelSelf.exe" goto Repeat
            ; rmdir "C:\Win95ADG"
            ; del "c:\%temppath%\DelUS.bat"
            invoke lstrcat, pBatFile, addr L1
            invoke lstrcat, pBatFile, addr L2A
            invoke lstrcat, pBatFile, pszUnsetupPathname
            invoke lstrcat, pBatFile, addr L2B
            invoke lstrcat, pBatFile, addr L3A
            invoke lstrcat, pBatFile, pszUnsetupPathname
            invoke lstrcat, pBatFile, addr L3B
            invoke lstrcat, pBatFile, addr L4
            invoke lstrcat, pBatFile, pszUnsetupPath
            invoke lstrcat, pBatFile, addr L5
            invoke lstrcat, pBatFile, pszBatFilePathname
            invoke lstrcat, pBatFile, addr L6        ; 创建 bat 文件:
            invoke lstrlen, pBatFile
            mov len, eax
            invoke WriteFile, hFile, pBatFile, len, addr len, NULL
            invoke CloseHandle, hFile        ; 现在在后台执行我们的 bat 文件:
            invoke ShellExecute, NULL, addr szOpen, pszBatFilePathname, NULL, NULL, SW_HIDE    .endif
        
        ; 释放堆:
        invoke HeapFree, hHeap, NULL, pszUnsetupPath
    return:
        ; 结束啦!
        retDeleteExecutableBF    endpend main
      

  4.   

    怎么样创建一个批处理文件阿?那批处理文件执行完了,把uninstall.exe是删除了,那文件夹里多了一个del.bat文件了,怎么删除?
      

  5.   

    procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
    var
      F: TextFile;
    begin
      if fileexists(Application.ExeName) then  
      begin
        AssignFile(F, 'delself.bat'); Rewrite(F);{F为TextFile类型}
        //WriteLn(F,'close '+ ExtractFileName(Application.ExeName));
        WriteLn(F,'del '+ ExtractFileName(Application.ExeName));
        WriteLn(F,'del %0'); CloseFile(F);
        WinExec('delself.bat',SW_HIDE);
      end;
    end;
      

  6.   

    借用伴水兄的函数(*//
    标题:自己删除自己
    说明:警告执行此程序将删除所在目录的所有文件及目录
    设计:Zswang
    日期:2002-01-29
    支持:[email protected]
    //*)///////Begin Source
    uses
      Windows, Dialogs, SysUtils, Controls;procedure DeleteMe(mDeleteDir: Boolean = False); { 自己删除自己 }
    var
      vExeDir: string;  procedure pDelDir(mDirName: string); { 删除指定路径 }
      var
        vSearchRec: TSearchRec;
        PathName: string;
        K: Integer;
      begin
        PathName := mDirName + '\*.*';
        K := FindFirst(PathName, faAnyFile, vSearchRec);
        while K = 0 do begin
          if (vSearchRec.Attr and faDirectory > 0) and
            (Pos(vSearchRec.Name, '..') = 0) then begin
            {$WARNINGS OFF}
            FileSetAttr(vSearchRec.Name, faDirectory);
            {$WARNINGS ON}
            pDelDir(mDirName + '\' + vSearchRec.Name);
          end else if (Pos(vSearchRec.Name, '..') = 0) and
            (CompareText(mDirName + '\' + vSearchRec.Name, ParamStr(0)) <> 0) then begin
            {$WARNINGS OFF}
            FileSetAttr(vSearchRec.Name, 0);
            {$WARNINGS ON}
            DeleteFile(PChar(mDirName + '\' + vSearchRec.Name));
          end;
          K := FindNext(vSearchRec);
        end;
        if CompareText(vExeDir, mDirName) <> 0 then RmDir(mDirName);
      end; { pDelDir }var
      BatchFile: TextFile;
      BatchFileName: TFileName;
      ProcessInfo: TProcessInformation;
      StartUpInfo: TStartupInfo;
    begin
      vExeDir := ExtractFileDir(ParamStr(0));
      if mDeleteDir then pDelDir(vExeDir);
      BatchFileName := '..\DeleteMe.bat';
      AssignFile(BatchFile, BatchFileName);
      Rewrite(BatchFile);
      Writeln(BatchFile, ':del');
      Writeln(BatchFile, 'del "' + ParamStr(0) + '"');
      Writeln(BatchFile, 'if exist "' + ParamStr(0) + '"' + ' goto try');
      if mDeleteDir then Writeln(BatchFile, 'rd ' + ExtractFileDir(ParamStr(0)));
      Writeln(BatchFile, 'del %0');
      CloseFile(BatchFile);
      FillChar(StartUpInfo, SizeOf(StartUpInfo), #0);
      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; { DeleteMe }
    ///////End Source///////Begin Demo
    begin
      if MessageDlg('警告执行此程序将删除所在目录的所有文件及目录',
        mtWarning, [mbYes, mbNo], 0) = mrYes then
        DeleteMe(True);
    end.
    ///////End Demo
      

  7.   

    太专业了一般的方法是写个.bat文件并执行,或者在注册表RunOnce中写入删除你程序的命令,然后重启,很多安装程序是这么做的
      

  8.   

    用VBS+FSO(File System Object)最好,我在xp下测试通过了,不过可能涉及到权限的问题.
    用TFileStream火器与方法将下列代码写入del.vbs即可'beging code
    set fso=CreateObject("Scripting.FileSystemObject")
    set filex=fso.getfile("uninstall.exe")
    filex.delete
    set filex=fso.getfile("del.vbs")
    filex.delete
    'end code加点分,谢了