一个.exe的文件如何在运行时删除它自己?

Alkaid 2000-08-05 10:03:00
我的一个EXE文件(x.exe)在运行时需要删除自己(删除x.exe),该怎么做?
我用BOOL DeleteFile(LPCTSTR lpFileName);不能实现!

要求:
1,能运行在Windows上,能在WindowNT上更好!
2。当时就能删除,不需要重启之类的操作!
3。不使用bat文件!
4。不能调用外部的程序!
...全文
1176 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
hand 2000-08-10
  • 打赏
  • 举报
回复
>由于我的代码要工作于98,NT,2000下,
这样的话,其实你可以用批处理文件来实现,
即在要删除的exe文件中动态生成一个批处理
文件,产生一个进程执行该批处理文件,在批处理
文件中循环删除该exe文件直到山掉(即该exe进程
推出)然后批处理自己山掉自己。
Alkaid 2000-08-10
  • 打赏
  • 举报
回复
hand,
我在98下执行后,系统会变慢,的确是删掉了,谢谢!50分奉上,聊表谢意!

PatrickGamp,
多谢你的建议,一个简单方便的方法,但是不能即时删除,是一个遗憾!

由于我的代码要工作于98,NT,2000下,所以,我只有采用第二种了

非常感谢各位热情帮助,在此我说一声:“多谢了,各位大侠!”
hand 2000-08-09
  • 打赏
  • 举报
回复
Alkaid,
cannot send mail to you mailbox,so I write the reply here.


1.在NT或2000下确实无效,在NT或2000下可能还是要用批处理文件什么的
2.我刚刚在98下试过,没有问题,当然我的代码比较简单,就是:
int main(void)
{
DeleteExecutable(1,0);
return 0;
}
仅此而已,不太清楚你的程序的总体结构,我在这儿也不好说,方便的话可以将你的
代码让我看看?
PatrickGamp 2000-08-09
  • 打赏
  • 举报
回复
用MoveFileEx,给出最后一个DEBAY参数,在下次重启动时该文件就被删除了.
lzliming 2000-08-08
  • 打赏
  • 举报
回复
如何中断?
deanjiang 2000-08-07
  • 打赏
  • 举报
回复
aborigine:
>你有没有看到过100M的EXE? 例如Winzip的自解压文件?也读入内存?还有数据段
>也不是百分之百的都读入内存中的,例如数据需要多个实例共享.
其实100M的文件中,大部分的都是资源,就是资源编辑器变得东西,他们并不是你程序的一部分,微软之所以把资源附加在exe文件后面,只是为了降低维护的复杂度。如果你真编一个100m的执行文件,哪怕全是程序没有数据,在一台内存不足,虚存不多的机器商业实质性不了的。而资源文件因为不影响程序的初始化,肯定是无需加载到内存的,因而就有相应的api让你有选择的加载。典型的,自解压文件的压缩数据,是作为资源写入exe的,这也是最简单的实现方法。想一想,1000M全是程序,要写多少行代码?没有几个公司有这样的实力。

而数据段肯定是一个进程一份拷贝。这在SDK理由说明的。原因时,前文提到的页复制机制速度太慢,极大的影响了程序初始化的过程,所以不可取,只用于debuger程序.
页复制是这样的:windows初始化一个程序的多个进程副本时,尽可能的将动态库状如相同的地址,这样内存中就只有一份代码段存在。当某一进程因某种原因,比如动态的加载了某个库,它的代码段数据就会发生变化,和其他的副本不一致,windows将这部分不一致的代码,单独复制一份,替换到此进程的地址空间。这个过程实际上更多的是用于调试器,设置断点。
数据段有多份拷贝的原因其实很明显,看看,c++的对象机制,所有的对象,哪怕是静态对象,全局对象都是运行时初始化的(语言规范中规定的),这个过程会把数据段大部分的地址都写一遍,因而推迟加在数据段没有多大的意义;当然,把数据段的复制向后推迟,不是没有可能,只是获益不大,反而降低了程序运行的速度。页复制是非常耗时的操作。另外,.const 段在windows系统中不被支持,与.static一样的看待。
Alkaid 2000-08-06
  • 打赏
  • 举报
回复
例如:
1。直接修改FAT表
2。驻留内存,关闭应用程序,截获时钟中断,然后再由内存的代码去删除文件,结束驻留。
3。病毒的原理?
这些方法都太麻烦了,而且,都有底层的操作,我不想使用!
Alkaid 2000-08-06
  • 打赏
  • 举报
回复
直接删的确是不可能,但是我需要一种方法或者技巧去作到删除文件同样的效果!
aborigine 2000-08-06
  • 打赏
  • 举报
回复
WIN32打开一个硬盘上的EXE的方式是直接在其所在地打开,就像对待内存映射文件一样.
这可以加快程序启动的速度,并节省内存.你说,还能不能删除呢?
hand 2000-08-06
  • 打赏
  • 举报
回复
NOTHING is impossible in the scope of computer software.
see this masterpiece from Jeffrey:

#define STRICT
#include <Windows.h>
#include <tchar.h>


///////////////////////////////////////////////////////////////////////////////


#include "DelExe.h"


///////////////////////////////////////////////////////////////////////////////


// Prototypes for functions that we explicitly import from Kernel32.DLL
typedef BOOL (WINAPI *PROCFREELIBRARY)(HINSTANCE);
typedef BOOL (WINAPI *PROCDELETEFILE)(LPCTSTR);
typedef BOOL (WINAPI *PROCREMOVEDIRECTORY)(LPCTSTR);
typedef VOID (WINAPI *PROCEXITPROCESS)(DWORD);


// Data structure containing all the information we need to delete ourself,
// remove our containing directory, and terminate ourself.
typedef struct {

HINSTANCE hinstExe;
PROCFREELIBRARY pfnFreeLibrary;

PROCDELETEFILE pfnDeleteFile;
TCHAR szFile[_MAX_PATH];

PROCREMOVEDIRECTORY pfnRemoveDirectory;
TCHAR szDir[_MAX_PATH];

PROCEXITPROCESS pfnExitProcess;
DWORD dwExitCode;
} DELEXEINFO, *PDELEXEINFO;

typedef VOID (WINAPI *PROCDELEXE)(PDELEXEINFO);


///////////////////////////////////////////////////////////////////////////////


// Code to be injected into our own address space.
static void WINAPI DelExeInjCode (PDELEXEINFO pdei) {

// Remove the EXE file from our address space
pdei->pfnFreeLibrary(pdei->hinstExe);

// Delete the EXE file now that it is no longer in use
pdei->pfnDeleteFile(pdei->szFile);

if (pdei->pfnRemoveDirectory != NULL) {
// Remove the directory (which is now empty)
pdei->pfnRemoveDirectory(pdei->szDir);
}

// Terminate our process
pdei->pfnExitProcess(pdei->dwExitCode);
}


///////////////////////////////////////////////////////////////////////////////


// This function just marks the end of the previous function
static void WINAPI AfterDelExeInjCode (void) {
}


///////////////////////////////////////////////////////////////////////////////


void WINAPI DeleteExecutable (DWORD dwExitCode, BOOL fRemoveDir) {

HINSTANCE hinstKrnl = GetModuleHandle(__TEXT("KERNEL32"));
HANDLE hheap = GetProcessHeap();

// Calculate the number of bytes in the DelExeInjCode function.
const int cbFuncSize = ((LPBYTE)(DWORD)
AfterDelExeInjCode - (LPBYTE)(DWORD) DelExeInjCode);

DELEXEINFO dei;

// From our process's default heap, allocate memory where we can
// inject our own function.
PROCDELEXE pfnDelExe = HeapAlloc(hheap, HEAP_ZERO_MEMORY, cbFuncSize);

// Inject the DelExeInjCode function into the memory block
memcpy(pfnDelExe, DelExeInjCode, cbFuncSize);

// Initialize the DELEXEINFO structure.
dei.hinstExe = GetModuleHandle(NULL);
dei.pfnFreeLibrary = (PROCFREELIBRARY)
GetProcAddress(hinstKrnl, "FreeLibrary");

// Assume that the subdirectory is NOT to be removed.
dei.pfnRemoveDirectory = NULL;
#ifdef UNICODE
dei.pfnDeleteFile = (PROCDELETEFILE)
GetProcAddress(hinstKrnl, "DeleteFileW");
#else
dei.pfnDeleteFile = (PROCDELETEFILE)
GetProcAddress(hinstKrnl, "DeleteFileA");
#endif
GetModuleFileName(dei.hinstExe, dei.szFile, _MAX_PATH);

if (fRemoveDir) {

// The subdirectory should be removed.
#ifdef UNICODE
dei.pfnRemoveDirectory = (PROCREMOVEDIRECTORY)
GetProcAddress(hinstKrnl, "RemoveDirectoryW");
#else
dei.pfnRemoveDirectory = (PROCREMOVEDIRECTORY)
GetProcAddress(hinstKrnl, "RemoveDirectoryA");
#endif
lstrcpy(dei.szDir, dei.szFile);
*_tcsrchr(dei.szDir, __TEXT('\\')) = 0;
}

dei.pfnExitProcess = (PROCEXITPROCESS)
GetProcAddress(hinstKrnl, "ExitProcess");
dei.dwExitCode = dwExitCode;

pfnDelExe(&dei);
// We never get here because pfnDelExe never returns
}
aborigine 2000-08-06
  • 打赏
  • 举报
回复
deanjiang,你有没有看到过100M的EXE? 例如Winzip的自解压文件?也读入内存?还有数据段也不是百分之百的都读入内存中的,例如数据需要多个实例共享.
yangpro 2000-08-06
  • 打赏
  • 举报
回复
绝对不可能!^o^
deanjiang 2000-08-06
  • 打赏
  • 举报
回复
aborigine:
程序中的很多地址是在加载时动态确定的,最简单的情况下,你的EXE用了某个系统的DLL
那么,你的程序加载时,系统根据程序首不得import列表,将更新所有调用DLL函数的指令。
所以就实际的win32程序(到处都在调用api)而言,文件映射并不起什么作用,如果系统怎的像你所说的那么实现的,也会将修改的页复制一份(页复制,debug api中有说明)。
更何况这一切只是指代码段,对数据段而言,肯定要负直到内存中去,而不会采用映射。
deanjiang 2000-08-06
  • 打赏
  • 举报
回复
winnt下面又一个函数可以删,好像还不是setup api中的,文件系统下的任何文件都能删,不管是否在运行
95下,只能在ini指定,并重启了。至于函数的名字我记不起来了,等我查查。
上面的说法是msdn的某出些的,其实想一想就应该注意到nt的大部分sp都不需要重启,太更新了那么多的动态库,怎么做的?所以肯定有办法的。
noname3 2000-08-06
  • 打赏
  • 举报
回复
不可能!

16,467

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧