方法1,调用BAT文件。
//向指定文件写入文本。如果文件不存在就创建。 int WriteTextToFile(const char szFileName[], const char *lpszText) { FILE *pfile = fopen(szFileName, "w+"); if (pfile == NULL) return -1; int nWriteByte = fprintf(pfile, lpszText); fclose(pfile); return nWriteByte; } void DeleteApplicationSelf() //可以达到效果 { const char szFileName[] = "DeleteBat.bat";//使用批处理 const char szDeleteBatText[] = "@ echo off\n del %%1\"\n del %%0"; //创建BAT文件并写入内容 WriteTextToFile(szFileName, szDeleteBatText); //设置本程序进程基本为实时执行,快速退出。 SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); //通知资源管理器不显示本程序,当然如果程序没有真正的删除,刷新资源管理器后仍会显示出来的。 SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, _pgmptr, NULL); //运行bat文件来删除程序 char szFilePath[MAX_PATH]; sprintf(szFilePath, "\"%s\"", _pgmptr); ShellExecute(NULL, "open", "DeleteBat.bat", szFilePath, NULL, SW_HIDE); ExitProcess(0); }
调用起来非常方便:直接一个DeleteApplicationSelf()就完成了任务。
方法二。调用系统的cmd程序并传入参数。
void DeleteApplicationSelf() { char szCommandLine[MAX_PATH + 10]; //设置本程序进程基本为实时执行,快速退出。 SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); //通知资源管理器不显示本程序,当然如果程序没有真正的删除,刷新资源管理器后仍会显示出来的。 SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, _pgmptr, NULL); //调用cmd传入参数以删除自己 char szFilePath[MAX_PATH]; sprintf(szFilePath, "\"%s\"", _pgmptr); sprintf(szCommandLine, "/c del /q %s", szFilePath); ShellExecute(NULL, "open", "cmd.exe", szCommandLine, NULL, SW_HIDE); ExitProcess(0); }
调用方法与前面相同。
这二种方法都不会出现DOS程序窗口,完全达到了无影无踪的删除效果,更加不会出现有的程序自删除后仍显示程序图标,要刷新资源管理器后才发现程序被删除了。
再对代码作下讲解:
1._pgmptr 的定义为extern char * _pgmptr,stdlib.h文件对其说明为:points to the module (EXE) name。使用_pgmptr与使用GetModuleFileName(NULL, szExePath, MAX_PATH);来得到程序的路径是等效的。但是,绝对要加上""双引号后才能作参数传给批处理程序,不然会出错。
2.ShellExecute()最后一个参数为SW_HIDE表示隐藏窗口。
3.DOS命令del的/q参数表示安静模式,这样删除文件时就不会出现要求用户确认的提示对话框了。
附:二种方法都要加入头文件及lib库
#include <windows.h> #include <stdlib.h> #include <shellapi.h> #include <shlobj.h> #pragma comment(lib, "shell32.lib")