自毁程序


有种需求需要程序双击执行后删除自己
Writing a self destructing exe file
Explains how you can have a program delete itself once it has finished running without a reboot

Introduction

Uninstall programs typically want to delete themselves at the end of the un-installation, but executable cannot delete itself by simply calling the DeleteFile function. By calling the Selfdestruct() function showed below before program exit, the calling executable will be destroyed as soon as possible. The method shown in this article works on all Win32 platforms and there is no need to reboot.



1
//============================================================================ 2 // Name : Test.cpp 3 // Author : Forever 4 // Version : 5 // Copyright : Your copyright notice 6 // Description : Hello World in C++, Ansi-style 7 //============================================================================ 8 #include <iostream> 9 #include <windows.h> 10 #include <stdlib.h> 11 #include <stdio.h> 12 #include <string.h> 13 #include <string> 14 #include <malloc.h> 15 using namespace std; 16 static const char tempbatname[] = "_uninsep.bat" ; 17 18 void Selfdestruct() 19 { 20 // temporary .bat file 21 static char templ[] = 22 ":Repeat " 23 "del "%s" " 24 "if exist "%s" goto Repeat " 25 "rmdir "%s" " 26 "del "%s"" ; 27 28 29 char modulename[_MAX_PATH] ; // absolute path of calling .exe file 30 char temppath[_MAX_PATH] ; // absolute path of temporary .bat file 31 char folder[_MAX_PATH] ; 32 // absolute path of temporary .bat file 33 GetTempPath(_MAX_PATH, temppath) ; 34 strcat(temppath, tempbatname) ; 35 // absolute path of calling .exe file 36 GetModuleFileName(NULL, modulename, MAX_PATH) ; 37 strcpy (folder, modulename) ; 38 char *pb = strrchr(folder, '\'); 39 if (pb != NULL) 40 *pb = 0 ; 41 42 HANDLE hf ; 43 44 hf = CreateFile(temppath, GENERIC_WRITE, 0, NULL, 45 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ; 46 //Long,如执行成功,则返回文件句柄。INVALID_HANDLE_VALUE表示出错,会设置GetLastError。即使函数成功,但若文件存在,且指定了CREATE_ALWAYS 或 OPEN_ALWAYS,GetLastError也会设为ERROR_ALREADY_EXISTS 47 if (hf != INVALID_HANDLE_VALUE) 48 { 49 DWORD len ; 50 char *bat ; 51 //缓存大小最大1024 52 bat = (char*)alloca(strlen(templ) +strlen(modulename) * 2 + strlen(temppath) + 20); 53 54 wsprintf(bat, templ, modulename, modulename, folder, temppath) ; 55 56 WriteFile(hf, bat, strlen(bat), &len, NULL) ; 57 CloseHandle(hf) ; 58 59 ShellExecute(NULL, "open", temppath, NULL, NULL, SW_HIDE); 60 } 61 } 62 int main() { 63 cout << "Hello Forever" << endl; // prints Hello Forever 64 Selfdestruct(); 65 return 0; 66 } 67 /* 68 VC 部分 69 API中函数原形为: DWORD GetTempPath(DWORD nBufferLength, LPTSTR lpBuffer) 70 GetTempPath有关参数说明如下: 71 StrLen = GetTempPath(NAME_LEN, OutPath) 72 其中: 73 OutPath: 是输出临时文件夹名称的变量,它的初始值为NAME_LEN个空格,函数调用后,就不是空格了,它会把取得的临时文件夹名称存入此变量。 74 NAME_LEN: 是告诉函数OutPath变量的长度。 75 StrLen:是取得的临时文件夹名称的长度。 76 举例如下: 77 StrLen = GetTempPath(NAME_LEN, OutPath) 78 调用后OutPath=“C:DOCUME~1LJL889~1LOCALS~1Temp ” 79 那么,left(OutPath,StrLen )就是准确的临时文件夹名称了。 80 81 (C++) 82 DWORD WINAPI GetModuleFileName( 83 _In_opt_ HMODULE hModule, 84 _Out_ LPTSTR lpFilename, 85 _In_ DWORD nSize 86 ); 87 函数参数 88 HMODULE hModule 装载一个程序实例的句柄。如果该参数为NULL,该函数返回该当前应用程序全路径。 89 LPTSTR lpFileName 是你存放返回的名字的内存块的指针,是一个输出参数 90 DWORD nSize,装载到缓冲区lpFileName的最大值 91 函数返回值 92 如果返回为成功,将在lpFileName的缓冲区当中返回相应模块的路径,如果所设的nSize过小,那么返回仅按所设置缓冲区大小返回相应字符串内容。 93 如果函数失败,返回值将为0,利用GetLastError可获得异常代码。 94 VC实例源代码编辑 95 #include <windows.h> 96 #include <stdio.h> 97 BOOL CreateSampleService() 98 { 99 TCHAR szPath[MAX_PATH]; 100 if( !GetModuleFileName( NULL, szPath, MAX_PATH ) ) 101 { 102 printf("GetModuleFileName failed (%d) ", GetLastError()); 103 return FALSE; 104 } 105 return TRUE; 106 } 107 如果想获得某个正在运行的EXE或者DLL的全路径可以这样写代码 108 GetModuleFileNameEx(hProcess,hInst,lpFile,MAX_PATH);//注意下缓冲区就行了。 109 C语言函数编辑 110 函数简介 111 112 函数名称: strrchr 113 函数原型:char *strrchr(const char *str, char c); 114 所属库: string.h 115 函数功能:查找一个字符c在另一个字符串str中末次出现的位置(也就是从str的右侧开始查找字符c首次出现的位置),并返回这个位置的地址。如果未能找到指定字符,那么函数将返回NULL。 116 相关函数: strchr 117 例子 118 #include <string.h> 119 #include <stdio.h> 120 int main(void) 121 { 122 char string[20]; 123 char *ptr, c = 'r'; 124 strcpy(string, "There are two rings"); 125 ptr = strrchr(string, c); 126 if (ptr) 127 printf("The character %c is at position: %s ", c, ptr); 128 else 129 printf("The character was not found "); 130 return 0; 131 } 132 strrchr返回的指针应当指向"rings"里的'r',而不是“There”或"are"里的'r'。 133 运行结果是:The character r is at position:rings 134 135 HANDLE WINAPI CreateFile( 136 _In_ LPCTSTR lpFileName, 137 _In_ DWORD dwDesiredAccess, 138 _In_ DWORD dwShareMode, 139 _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes, 140 _In_ DWORD dwCreationDisposition, 141 _In_ DWORD dwFlagsAndAttributes, 142 _In_opt_ HANDLE hTemplateFile 143 ); 144 Long,如执行成功,则返回文件句柄。INVALID_HANDLE_VALUE表示出错,会设置GetLastError。即使函数成功,但若文件存在,且指定了CREATE_ALWAYS 或 OPEN_ALWAYS,GetLastError也会设为ERROR_ALREADY_EXISTS 145 参数类型及说明 146 函数声明HANDLE CreateFile( 147 LPCTSTR lpFileName, //普通文件名或者设备文件名 148 DWORD dwDesiredAccess, //访问模式(写/读) 149 DWORD dwShareMode, //共享模式 150 LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性的指针 151 DWORD dwCreationDisposition, //如何创建 152 DWORD dwFlagsAndAttributes, //文件属性 153 HANDLE hTemplateFile //用于复制文件句柄);参数说明 154 155 156 int wsprintf( LPTSTR lpOut, // 输出缓冲区,最大为1024字节 157 LPCTSTR lpFmt, // 格式字符串 , 158 ... // 需输出的参数); 159 使用此函数可将数字转为字符串; 160 例:int x=6; 161 LPTSTR szBuffer=new TCHAR[1024];);//定义并申请输入缓冲区空间 162 wsprintf(szBuffer,“%d“,x);//应用 163 另外: 164 MessageBox(NULL,szBuffer,““,MB_OK); 165 */
原文地址:https://www.cnblogs.com/CentForever/p/7532151.html