中国IT动力,最新最全的IT技术教程
最新100篇 | 推荐100篇 | 专题100篇 | 排行榜 | 搜索 | 在线API文档
首 页 | 程序开发 | 操作系统 | 软件应用 | 图形图象 | 网络应用 | 精文荟萃 | 教育认证 | 硬件维护 | 未整理篇 | 站长教程
ASP JS PHP工程 ASP.NET 网站建设 UML J2EESUN .NET VC VB VFP 网络维护 数据库 DB2 SQL2000 Oracle Mysql
服务器 Win2000 Office C DreamWeaver FireWorks Flash PhotoShop 上网宝典 CorelDraw 协议大全 网络安全 微软认证
硬件维护  CPU  主板  硬盘  内存  显卡  显示器  键盘鼠标  声卡音箱  打印机  机箱电源  BIOS  网卡  C#  Java  Delphi  vs.net2005
  当前位置:> 程序开发 > 编程语言 > Visual C++ > 一般性编程问题
如何简单实现可执行文件的自我删除
作者:未知 时间:2005-07-20 14:08 出处:VC知识库 责编:chinaitpower
              摘要:如何简单实现可执行文件的自我删除

如何简单实现可执行文件的自我删除

作者:zyq654321

可执行文件即 EXE 文件在运行过程中,由系统管理其打开的句柄。此时对该文件的一些操作是被系统禁止的,比如删除操作。然而在某些场合,可能须要程序有自我删除的功能,也就是程序运行结束后删除自身。基于这个想法,可以有一种很简单的方法来实现这个基本功能。

本方法基于两点来实现删除功能。一是利用 windows 的 command program 的删除文件操作;再者就是启动新的进程来执行这个删除操作。下面就仔细说明。

Windows 中的 command program 是一个系统的 shell program. 在 windows95/98/Me 中,其文件名为 command.com ,而在 NT/2000/XP 中则是 cmd.exe 。我们可以通过环境变量 COMSPEC 得到其全路径名。

假定目前我们所使用的是 XP ,在命令行中输入 :

cmd.exe /?

即得到 command shell 的使用方法;其中 /c 的含义是:执行字符串指定的命令然后终断,这正是我们所须要的。这样利用 command shell 删除一个文件的命令如下:

cmd.exe /c del mypro.exe

这里要注意一点,文件名应该是短文件名(文件名不得超过 8 个字符 , 后缀不超过 3 个字符)。如果实际文件是长文件句,那么程序中我们可以用 GetShortPathName 这个 API 函数来转换。

接下来我们要做是如何在一新的进程中成功的执行这一指令。起来一个新进程的命令主要有 ShellExecute 和 CreateProcess 。

先使用 ShellExecute 为例。在程序的结束处使用如下语句:

ShellExecute(NULL, "open","cmd.exe", "/c del mypro.exe ", NULL, SW_HIDE);

编译后运行文件发现执行成功,文件运行完后被删除。但是后面做多次实验后,发现有时文件执行完后并不会被删除。通过分析,认为在删除操作执行时,可执行文件还未关闭。也就是说只有在执行文件的进程关闭后,执行删除操作的进程才能完成操作。这样就有了一个问题,系统负责进程和线程的调度执行,我们无法人为规定进程或线程以某种秩序执行。

对此我的解决办法是,建立执行删除操作的进程时设定其为挂起状态,从而为其的设定一个低优先级别,同时提高执行文件的进程级别,然后才正式起动新进程。这样基本可以保证两个进程的先后执行。这样新的解决方法就是用CreateProcess以CREATE_SUSPEND标志来建立新进程,然后用SetPriorityClass来设定相应的优先级,主进程的优先级是HIGH_PRIORITY_CLASS,而执行删除操作的进程的优先级是IDLE_PRIORITY_CLASS。经过数百次的测试,删除操作都是成功的。

下面是一个封装了删除操作的函数,函数内起动一个进程执行command shell的del命令。在程序最后结束处调用它,就可以简单的实现程序的自删除功能。
#include <windows.h>
#include <shellapi.h>
#include <stdio.h>

int DeleteMyExe()
{
	TCHAR tcsExename[MAX_PATH];
	TCHAR tcsParam[MAX_PATH * 2];
	TCHAR tcsCmd[MAX_PATH];
	HANDLE hProcess = NULL;

	// get exe filename and command shell program
	if( 0 == GetModuleFileName(NULL, tcsExename, MAX_PATH) 
		||  0 == GetEnvironmentVariable(_T("COMSPEC"), tcsCmd, MAX_PATH))
		FAILRET;

	// get short filename for command shell program
	if( 0 == GetShortPathName(tcsExename, tcsExename, MAX_PATH))
		FAILRET;
	
	// create a command process, set its priority, then start it.
	STARTUPINFO si;
	PROCESS_INFORMATION pi;

	ZeroMemory( &si, sizeof(si) );
	si.cb          = sizeof(si);
	si.dwFlags     = STARTF_USESHOWWINDOW;
	si.wShowWindow = SW_HIDE;
	ZeroMemory( &pi, sizeof(pi) );

	_stprintf(tcsParam, _T("%s /c del %s"), tcsCmd, tcsExename);
	if(!CreateProcess(NULL,
					  tcsParam,
					  NULL,
					  NULL,
					  FALSE,
					  CREATE_SUSPENDED,
					  NULL,
					  NULL,
					  &si,
					  &pi))
	{
		return GetLastError();
	}

	// heigthen priority of the current process
	SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);    

	// set file attribute to normal 
	SetFileAttributes(tcsExename, FILE_ATTRIBUTE_NORMAL);

	// depress priority of command process, then start it
	SetPriorityClass(pi.hProcess, IDLE_PRIORITY_CLASS);
	ResumeThread(pi.hThread);
    return 0;
}
(全文完)
关闭本页
 
首页 | 投资与合作 | 服务条款 | 隐私政策 | 收藏本站 | 设为首页 | 新用户注册 | 免责声明 | 使用帮助
Copyright ©2005-2008 chinaitpower.com All rights reserved. www.chinaitpower.com 版权所有