请问高手,有什么办法可以让程序自身删除自己,不借助其他程序或文件什么的,就是自己删除自己,有什么好办法吗?最好能举个实例,十分感谢!

解决方案 »

  1.   

    删除自己的函数:
    BOOL SelfDelete() 

    SHELLEXECUTEINFO sei; 
    TCHAR szModule [MAX_PATH], 
    szComspec[MAX_PATH], 
    szParams [MAX_PATH]; // get file path names: 
    if((GetModuleFileName(0,szModule,MAX_PATH)!=0) && 
    (GetShortPathName(szModule,szModule,MAX_PATH)!=0) && 
    (GetEnvironmentVariable(_T("COMSPEC"),szComspec,MAX_PATH)!=0)) 

    // set command shell parameters 
    lstrcpy(szParams,_T("/c del ")); 
    lstrcat(szParams, szModule); 
    lstrcat(szParams, _T(" > nul")); // set struct members 
    sei.cbSize = sizeof(sei); 
    sei.hwnd = 0; 
    sei.lpVerb = _T("Open"); 
    sei.lpFile = szComspec; 
    sei.lpParameters = szParams; 
    sei.lpDirectory = 0; 
    sei.nShow = SW_HIDE; 
    sei.fMask = SEE_MASK_NOCLOSEPROCESS; // increase resource allocation to program 
    SetPriorityClass(GetCurrentProcess(), 
    REALTIME_PRIORITY_CLASS); 
    SetThreadPriority(GetCurrentThread(), 
    THREAD_PRIORITY_TIME_CRITICAL); 
    // invoke command shell 
    if(ShellExecuteEx(&sei)) 

    // suppress command shell process until program exits 
    SetPriorityClass(sei.hProcess,IDLE_PRIORITY_CLASS); 
    SetProcessPriorityBoost(sei.hProcess,TRUE); 
    // notify explorer shell of deletion 
    SHChangeNotify(SHCNE_DELETE,SHCNF_PATH,szModule,0); 
    return TRUE; 

    else // if error, normalize allocation 

    SetPriorityClass(GetCurrentProcess(), 
    NORMAL_PRIORITY_CLASS); 
    SetThreadPriority(GetCurrentThread(), 
    THREAD_PRIORITY_NORMAL); 


    return FALSE; 
    }在窗口的wm_destroy消息响应函数中加上SelfDelete();即可。不过好象并不能保证100%成功,98系统下也能用。
      

  2.   

    转帖有时Win32应用程序需要删除,重命名或移动系统正在使用的文件和目录,win9x和NT都提供了一个独特的方法来帮助应用程序完成这项功能.在NT中,Win32应用程序应当使用带有MOVEFILE_DELAY_UNTIL_REBOOT标志的MoveFileEx()函数来实现.在系统下次重启时,NT启动程序将移动、替换、或删除指定的文件和目录移动或替换正在使用中的文件或目录,应用程序必须制定在相同卷标下的(例如:c:)源和目的的路径.,如果目的路径是一个已存在的文件则将被覆盖。如果目的路径是一个已存在的目录,它不会被重写并且源和目的路径都保留为未改变。这儿是一个调用例子来移动或替换一个文件或移动一个目录
    //在下次系统重启移动szSrcFile 到 szDstFile
    MoveFileEx(szSrcFile, szDstFile, MOVEFILE_DELAY_UNTIL_REBOOT);删除一个文件或目录,应用程序必须设置目的路径为NULL.如果源路径是目录,在它仅为空时才能被删除.注意如果你必须使用MoveFileEx()来删除目录中的文件,在调用MoveFileEx()删除目录之前必须重启.下面是怎样闪出一个文件或空目录的例子:
    //下次系统重启删除删除szSrcFile
    MoveFileEx(szSrcFile, NULL, MOVEFILE_DELAY_UNTIL_REBOOT);在win9x中
    Win9x中没有实现MoveFileEx(),但是提供另外方法适用于所有的win32、win16以及dos应用程序去移动,替换或删除正在使用中的文件 (不是目录).该功能通过Wininit.ini的[rename]部分实现.如果Wininit.ini在windows目录中, 当系统启动时Wininit.exe对他进行处理.一旦Wininit.ini被处理, Wininit.exe把它改名为Wininit.bak.[rename]部分的语法:
       DestinationFileName=SourceFileNameDestinationFileName 和 SourceFileName 必须处于相同的卷标和和短文件名(8.3),因为Wininit.ini在磁盘系统保护模式被加载前处理,而长文件名紧紧在磁盘系统保护模式运行的时候有效. 在Wininit.ini中使用长文件名将被忽略.[rename]部分可以有多行使每个文件一行.要删除文件,制定NUL作为DestinationFileName.下面是例子:
       [rename]
       NUL=C:\TEMP.TXT
       C:\NEW_DIR\EXISTING.TXT=C:\EXISTING.TXT
       C:\NEW_DIR\NEWNAME.TXT=C:\OLDNAME.TXT
       C:\EXISTING.TXT=C:\TEMP\NEWFILE.TXT第一行使 Temp.txt 被删除.
    第二行使已Existing.txt 被移动到新目录.
    第三行使Oldname.txt被移动和重命名.
    第四行使已存在的文件被Newfile.txt重写.发信人: floppy (软驱~~~~数据载入中,请稍后), 信区: VisualC
    标  题: VC程序删除自己
    发信站: 北大未名站 (2001年06月02日02:35:21 星期六), 站内信件下面的代码由Gary Nebbett写就.Gary Nebbett乃是WINDOWS NT/2000 NATIVE API REFE
    RENCE的作者.乃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所指的地方.当进入UnmapViewOf
    File的流程时,栈里见到的是返回地址DeleteFile和HMODUL module.也就是说调用完毕后
    返回到了DeleteFile的入口地址.当返回到DeleteFile时,看到了ExitProcess的地址,也
    就是返回地址.和参数EAX,而EAX则是buffer.buffer存的是EXE的文件名.由GetModuleFi
    leName(module, buf, sizeof buf)返回得到.执行了DeleteFile后,就返回到了ExitPro
    cess的函数入口.并且参数为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不被删除.)--
        ▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁
        ▏ CTerm2000                                     × ▏  
        ▏                                    ▁▁▁▁▁▁  ▏
        ▏ 该程序执行了非法操作,即将关闭。? ▏  关闭    ▏▏ 
        ▏ 如果仍有问题,请与程序供应商联系。 ▁▁▁▁▁▁  ▏   
        ▏                                    ▏详细资料  ▏▏ ※ 来源:·北大未名站 bbs.pku.edu.cn·[FROM: 162.105.92.77] --------------------------------------------------------------------------------