- #include <Windows.h>
- #include <stdlib.h>
- #include <tchar.h>
- #include <iostream.h>
- BOOL DeleteFolder(LPCTSTR lpszPath)
- {
- SHFILEOPSTRUCT FileOp;
- ZeroMemory((void*)&FileOp,sizeof(SHFILEOPSTRUCT));
- FileOp.fFlags = FOF_NOCONFIRMATION;
- FileOp.hNameMappings = NULL;
- FileOp.hwnd = NULL;
- FileOp.lpszProgressTitle = NULL;
- FileOp.pFrom = lpszPath;
- FileOp.pTo = NULL;
- FileOp.wFunc = FO_DELETE;
- return SHFileOperation(&FileOp) == 0;
- }
- int main()
- {
- if (__argc == 1)
- {
- // Original EXE: Spawn clone EXE to delete this EXE
- // Copy this EXEcutable image into the user's temp directory
- char del;
- cout << "delete self or not?(y/n)/n";
- cin >> del;
- if(del == 'n')
- return 0;
- TCHAR szPathOrig[_MAX_PATH], szPathClone[_MAX_PATH];
- GetModuleFileName(NULL, szPathOrig, _MAX_PATH);
- GetTempPath(_MAX_PATH, szPathClone);
- GetTempFileName(szPathClone, __TEXT("Del"), 0, szPathClone);
- CopyFile(szPathOrig, szPathClone, FALSE);
- //***注意了***:
- // Open the clone EXE using FILE_FLAG_DELETE_ON_CLOSE
- HANDLE hfile = CreateFile(szPathClone,0, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, NULL);
- // Spawn the clone EXE passing it our EXE's process handle
- // and the full path name to the Original EXE file.
- TCHAR szCmdLine[512];
- HANDLE hProcessOrig = OpenProcess(SYNCHRONIZE, TRUE, GetCurrentProcessId());
- wsprintf(szCmdLine, __TEXT("%s %d /"%s/""), szPathClone, hProcessOrig, szPathOrig);
- STARTUPINFO si;
- ZeroMemory(&si, sizeof(si));
- si.cb = sizeof(si);
- PROCESS_INFORMATION pi;
- CreateProcess(NULL,szCmdLine,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi);
- CloseHandle(hProcessOrig);
- CloseHandle(hfile);
- // This original process can now terminate.
- }
- else
- {
- // Clone EXE: When original EXE terminates, delete it
- HANDLE hProcessOrig = (HANDLE) _ttoi(__targv[1]);
- WaitForSingleObject(hProcessOrig, INFINITE);
- CloseHandle(hProcessOrig);
- char str[256];
- memset(str,0,256);
- strcpy(str,__targv[2]);
- int len = strlen(str);
- while(true)
- {
- if(str[len] == '//')
- {
- str[len] = '/0';
- break;
- }
- str[len] = '/0';
- len--;
- }
- DeleteFolder(str);
- // DeleteFile(__targv[2]);
- // Delete the clone one
- SHELLEXECUTEINFO sei;
- TCHAR szModule [MAX_PATH],szComspec[MAX_PATH],szParams [MAX_PATH];
- //获取文件路径名
- if((GetModuleFileName(0,szModule,MAX_PATH)!=0) &&
- (GetShortPathName(szModule,szModule,MAX_PATH)!=0) &&
- (GetEnvironmentVariable("COMSPEC",szComspec,MAX_PATH)!=0))
- { //设置命令行参数。
- lstrcpy(szParams,"/c del ");FindWindow(NULL,NULL);
- lstrcat(szParams, szModule);
- lstrcat(szParams, " > nul");
- //初始化SHELLEXECUTEINFO结构成员
- sei.cbSize = sizeof(sei); //设置类型大小。
- //命令窗口进程句柄,ShellExecuteEx函数执行时设置。
- sei.hwnd = 0;
- sei.lpVerb = "Open"; //执行动作为“打开执行”。
- sei.lpFile = szComspec; //执行程序文件全路径名称。
- sei.lpParameters = szParams; //执行参数。
- sei.lpDirectory = 0;
- //显示方式,此处使用隐藏方式阻止出现命令窗口界面。
- sei.nShow = SW_HIDE;
- //设置为SellExecuteEx函数结束后进程退出。
- sei.fMask = SEE_MASK_NOCLOSEPROCESS;
- //创建执行命令窗口进程。
- if(ShellExecuteEx(&sei))
- { //设置命令行进程的执行级别为空闲执行,这使本程序有足够的时间从内存中退出。
- SetPriorityClass(sei.hProcess,IDLE_PRIORITY_CLASS);
- //设置本程序进程的执行级别为实时执行,这本程序马上获取CPU执行权,快速退出。
- SetPriorityClass(GetCurrentProcess(),REALTIME_PRIORITY_CLASS);
- SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);
- }
- }
- }
- // Insert code here to remove the subdirectory too (if desired).
- // The system will delete the clone EXE automatically
- // because it was opened with FILE_FLAG_DELETE_ON_CLOSE
- return(0);
- }
反安装程序雏形,参照网上两篇文章来改写的,在此感谢那些分享经验的人。
反安装程序至少有两个难点,一是自己删除自己,二是删除自己所在的那个文件夹。
我在“webnumen技术生活博客”找到了让程序自己删除自己的方法,但是要让程序删除自己所在的那个文件夹还不能实现,虽然在vc6.0中运行刚刚编译好了的程序,可以删除自己所在的那个Debug文件夹。但是直接运行已经生成好了的程序,根本不能删除自己所在的文件夹,顶多就是把和自己在同一个目录里的文件和文件夹都删除掉。
因此我又找到了“C+精探的专栏”,参考他的代码解决掉了第二个难点。
思路就是拷贝一个自己的附本到临时目录,然后启动那个附本,把自己的ID和路径做为参数传递给附本,并让自己正常退出。启动的那个附本所要做的工作就是根据原来的程序传递给他的参数来删除原程序所在的那个文件夹。删掉别人后,然后把自己干掉,具体是怎么干掉自己的,可以参考“webnumen技术生活博客”
webnumen技术生活博客
http://webnumen.blog.hexun.com/19268347_d.html
C+精探的专栏
http://blog.csdn.net/dpfordor/archive/2008/01/10/2032954.aspx