Chinaunix首页 | 论坛 | 博客
  • 博客访问: 381396
  • 博文数量: 715
  • 博客积分: 40000
  • 博客等级: 大将
  • 技术积分: 5005
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 14:46
文章分类

全部博文(715)

文章存档

2011年(1)

2008年(714)

我的朋友

分类:

2008-10-13 16:31:40

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

       本方法基于两点来实现删除功能。一是利用windowscommand 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函数来转换。

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

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

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

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

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

    下面是一个封装了删除操作的函数,函数内起动一个进程执行command shelldel命令。在程序最后结束处调用它,就可以简单的实现程序的自删除功能。

 

#include

#include

#include

 

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;

}

 

 


--------------------next---------------------

阅读(172) | 评论(0) | 转发(0) |
0

上一篇:why name Hercules

下一篇:阿喀琉斯故事

给主人留下些什么吧!~~