📄 uninstall.cpp
字号:
// Uninstall.cpp : Defines the entry point for the application.
//
// Module name: DeleteMe.cpp
// Written by: Jeffrey Richter
// Description: Allows an executable file to delete itself
#include "stdafx.h"
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <stdlib.h>
#define EVT_NAME _T("ExeDeleteEvent")
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR pszCmdLine, int nCmdShow)
{
HANDLE hProcessOrig, hEvent;
// if the command-line contains "PID:" this is the clone EXE, otherwise
// this is the original EXE
// if this is the original EXE
if (::_tcsstr(::GetCommandLine(), _T("PID:")) == NULL) {
// original EXE: spawn clone EXE to delete this EXE
TCHAR szPathOrig[MAX_PATH], szPathClone[MAX_PATH];
::GetModuleFileName(NULL, szPathOrig, sizeof(szPathOrig));
::GetTempPath(sizeof(szPathClone), szPathClone);
::GetTempFileName(szPathClone, _T("Del"), 0, szPathClone);
// copy this executable image into the user's temp directory
::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];
hProcessOrig = ::OpenProcess(SYNCHRONIZE, TRUE, GetCurrentProcessId());
::_stprintf(szCmdLine, _T("%s PID:%d EXE:\"%s\""), szPathClone,
hProcessOrig, szPathOrig);
STARTUPINFO si;
PROCESS_INFORMATION pi;
::ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
// create clone to delete original file executable
BOOL rc = ::CreateProcess(NULL,
szCmdLine,
NULL,
NULL,
TRUE,
0,
NULL,
NULL,
&si,
&pi);
// wait until child process is ready
::WaitForInputIdle(pi.hProcess, 1000);
// close original process handle (inherited by child process)
::CloseHandle(hProcessOrig);
// wait until clone EXE is running before deleting the executable file
::CloseHandle(hFile); // close and delete the clone EXE file
}
else { // clone EXE is running
TCHAR *ptr;
MessageBox(NULL, "clone", "clone", MB_OK);
// find process ID marker
ptr = ::_tcsstr(::GetCommandLine(), _T("PID:"));
ptr += ::_tcslen(_T("PID:")); // move to beginning of process ID
hProcessOrig = (HANDLE)::_ttoi(ptr); // convert and storeprocess ID
MessageBox(NULL, "clone2", "clone", MB_OK);
// wait for original EXE to finish
::WaitForSingleObject(hProcessOrig, INFINITE);
MessageBox(NULL, "clone3", "clone", MB_OK);
MessageBox(NULL, "clone4", "clone", MB_OK);
::CloseHandle(hProcessOrig); // close original EXE process handle
ptr = ::_tcsstr(ptr, _T("EXE:")); // find EXE file name marker
// go to start of the EXE file name (+ 1 to go past double-quote)
ptr += ::_tcslen(_T("EXE:")) + 1;
// find and remove ending double-quote
::_tcschr(ptr, _T('"'))[0] = _T('\0');
MessageBox(NULL, "clone5", "clone", MB_OK);
::DeleteFile(ptr); // delete the executable file
::RemoveDirectory("D:\\repository\\Products\\EZSetup\\sources\\Uninstall\\Debug");
// Insert code here to remove the subdirectory too (if desired).
// The system will delete the clone EXE automatically becauseit
// was opened with FILE_FLAG_DELETE_ON_CLOSE
}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -