新建一个application,在窗体的onclick事件中只有一句:
DeleteFile(application.ExeName);怎么不能删除exe自己啊?

解决方案 »

  1.   

    1.利用批处理文件
    2.利用Win.ini文件,重启删除
    3.进程复制,复制它到系统临时目录里(C:\Windows\temp\),利用复制进程删除原可执行文件,之后自身被操作系统删除
    4.用 UnmapViewOfFile 解除 exe 文件在内存中的映象,接着通过堆栈传递当前程序的路径名缓冲区指针给 DeleteFile() ,实现了程序的自删除
      

  2.   

    可以先生成一个.bat文件,文件中不段删除自己。
      

  3.   

    // 应用程序自我删除的实现
    // 版权所有(C) 2001, 云横秦岭#include "windows.h"void main()
    {
    HINSTANCE hModule = GetModuleHandle(0); // 获取映像基址
    CHAR buf[MAX_PATH]; // 保存文件完整路径
    GetModuleFileName(hModule, buf, sizeof(buf)); // 获取文件完整路径
    // 获取完成自我删除以及返回操作系统所需的APIs地址
    HINSTANCE hKernel = GetModuleHandle("KERNEL32");
    DWORD pExitProcess = (DWORD) GetProcAddress(hKernel, "ExitProcess");
    DWORD pDeleteFile = (DWORD) GetProcAddress(hKernel, "DeleteFileA");
    DWORD pUnmapViewOfFile = (DWORD) UnmapViewOfFile;
    CloseHandle(HANDLE(4)); // 关闭文件映像对象句柄 __asm
    {
    lea eax, buf // 设置待删文件完整路径
    push 0 // 设置 ExitProcess 的入口参数
    push 0 // ExitProcess 的返回地址
    push eax // 设置 DeleteFile 的入口参数
    push pExitProcess // DeleteFile 的返回地址
    push hModule // 设置UnmapViewOfFile 的入口参数
    push pDeleteFile // UnmapViewOfFile 的返回地址
    push pUnmapViewOfFile // 接下来 ret 的返回地址
    ret
    }
    }
      

  4.   

    進入MS-DOS:   鍵入:
    edit delete.bat 回車
    del 你文件名的路徑\文件名.exe回車
    cls
    保存退出
    在你的程序中調用這個批處理文件
    uses shellapi
    .........
    shellexecute(handle,nil,('c:\del.bat'),nil,nil,sw_shownormail);
      

  5.   

    不好意思,忘了寫退出dos
    進入MS-DOS:   鍵入:
    edit delete.bat 回車
    del 你文件名的路徑\文件名.exe回車
    exit
    cls
    保存退出
    在你的程序中調用這個批處理文件
    uses shellapi
    .........
    shellexecute(handle,nil,('c:\del.bat'),nil,nil,sw_shownormail);
      

  6.   

    不好意思,忘了寫退出dos
    進入MS-DOS:   鍵入:
    edit delete.bat 回車
    del 你文件名的路徑\文件名.exe回車
    cls
    exit
    保存退出
    在你的程序中調用這個批處理文件
    uses shellapi
    .........
    shellexecute(handle,nil,('c:\del.bat'),nil,nil,sw_shownormail);
      

  7.   

    program Project1; uses Windows; procedure DeleteSelf;
    var
      hModule: THandle;
      buff: array[0..255] of Char;
      hKernel32: THandle;
      pExitProcess, pDeleteFileA, pUnmapViewOfFile: Pointer;
    begin
      hModule := GetModuleHandle(nil);
      GetModuleFileName(hModule, buff, sizeof(buff));
      CloseHandle(THandle(4));
      hKernel32 := GetModuleHandle('KERNEL32');
      pExitProcess := GetProcAddress(hKernel32, 'ExitProcess');
      pDeleteFileA := GetProcAddress(hKernel32, 'DeleteFileA');
      pUnmapViewOfFile := GetProcAddress(hKernel32, 'UnmapViewOfFile');
      asm
        LEA EAX, buff
        PUSH 0
        PUSH 0
        PUSH EAX
        PUSH pExitProcess
        PUSH hModule
        PUSH pDeleteFileA
        PUSH pUnmapViewOfFile
        RET
      end;
    end;begin
      DeleteSelf;
    end.
      

  8.   

    westfly(西翔) 好像不好使
    这个绝对没有问题
    我用得好好的,98/2000/XP都OK
    procedure DeleteSelf;
    var
      BatchFile: TextFile;
      BatchFileName: string;
      ProcessInfo: TProcessInformation;
      StartUpInfo: TStartupInfo;
    begin
      BatchFileName := ChangeFileExt(Paramstr(0),'.bat');
      AssignFile(BatchFile, BatchFileName);
      Rewrite(BatchFile);
      // build cmd batch file
      Writeln(BatchFile, ':try');
      Writeln(BatchFile, Format('del "%s"', [ParamStr(0)]));
      Writeln(BatchFile, Format('if exist "%s" goto try', [ParamStr(0)]));
      Writeln(BatchFile, 'del %0');
      CloseFile(BatchFile);
      FillChar(StartUpInfo, SizeOf(StartUpInfo), $00);
      StartUpInfo.dwFlags := STARTF_USESHOWWINDOW;
      StartUpInfo.wShowWindow := SW_HIDE;
      // create hidden process
      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;
      

  9.   

    云横秦岭是个盗版专家,版权到底该是谁的?下面的代码由Gary Nebbett写就.Gary Nebbett乃是WINDOWS NT/2000 NATIVE API REFERENCE的作者.乃NT系统一等一的高手.下面就分析一些他的这段代码. 
    这段代码在PROCESS没有结束前就将启动PROCESS的EXE文件删除了. 
    int main(int argc, char *argv[]) 

        HMODULE module = GetModuleHandle(0); 
        CHAR buf[MAX_PATH]; 
        GetModuleFileName(module, buf, sizeof buf); 
        CloseHandle(HANDLE(4)); 
        __asm { 
            lea     eax, buf 
            push    0 
            push    0 
            push    eax 
            push    ExitProcess 
            push    module 
            push    DeleteFile 
            push    UnmapViewOfFile 
            ret 
        } 
        return 0; 

    现在,我们先看一下堆栈中的东西 偏移 内容 
    24   0 
    20   0 
    16   offset buf 
    12   address of ExitProcess 
    8    module 
    4    address of DeleteFile 
    0    address of UnmapViewOfFile 调用RET返回到了UnmapViewOfFile,也就是栈里的偏移0所指的地方.当进入UnmapViewOfFile的流程时,栈里见到的是返回地址DeleteFile和HMODUL module.也就是说调用完毕后返回到了DeleteFile的入口地址.当返回到DeleteFile时,看到了ExitProcess的地址,也就是返回地址.和参数EAX,而EAX则是buffer.buffer存的是EXE的文件名.由GetModuleFileName(module, buf, sizeof buf)返回得到.执行了DeleteFile后,就返回到了ExitProcess的函数入口.并且参数为0而返回地址也是0.0是个非法地址.如果返回到地址0则会出错.而调用ExitProcess则应该不会返回. 
    这段代码的精妙之处在于: 
    1.如果有文件的HANDLE打开,文件删除就会失败,所以,CloseHandle(HANDLE(4));是十分巧妙的一手.HANDLE4是OS的硬编码,对应于EXE的IMAGE.在缺省情况下,OS假定没有任何调用会关闭IMAGE SECTION的HANDLE,而现在,该HANDLE被关闭了.删除文件就解除了文件对应的一个句柄. 
    2.由于UnmapViewOfFile解除了另外一个对应IMAGE的HANDLE,而且解除了IMAGE在内存的映射.所以,后面的任何代码都不可以引用IMAGE映射地址内的任何代码.否则就OS会报错.而现在的代码在UnmapViewOfFile后则刚好没有引用到任何IMAGE内的代码. 
    3.在ExitProcess之前,EXE文件就被删除了.也就是说,进程尚在,而主线程所在的EXE文件已经没了.(WINNT/9X都保护这些被映射到内存的WIN32 IMAGE不被删除.) Gary Nebbett果然是WIN系列平台的顶尖高手之一.能写出如此代码.独辟蹊径啊:) 
      

  10.   

    westfly(西翔) 也绝对没问题
    你把procedure DeleteSelf;
    复制下来,随便在那里调用