release/win/code/HGRemoveOldApp/HGRemoveOldApp.cpp

402 lines
11 KiB
C++

#include <Windows.h>
#include <atlstr.h>
#include <vector>
#include <assert.h>
#include <shlobj.h>
#include <tlhelp32.h>
#include <psapi.h>
static void SplitString(const CStringA &src, CHAR sep, std::vector<CStringA> &dst)
{
dst.clear();
int len = src.GetLength();
CStringA str;
bool inParam = false;
for (int i = 0; i < len; ++i)
{
if (inParam || src[i] != sep)
{
str.AppendChar(src[i]);
if ('\"' == src[i])
inParam = !inParam;
}
else
{
if (!str.IsEmpty())
{
dst.push_back(str);
str.Empty();
}
}
}
if (!str.IsEmpty())
{
dst.push_back(str);
str.Empty();
}
}
static void RemoveQuotes(const CStringA& src, CStringA &dst)
{
dst = src;
while (dst.GetLength() >= 2 && dst[0] == '\"' && dst[dst.GetLength() - 1] == '\"')
{
dst = dst.Mid(1, dst.GetLength() - 2);
}
}
static CStringA GetInstallLocation(const CStringA& guid)
{
CStringA strInstallLoc;
HKEY hKey = NULL;
CStringA strSubKey;
strSubKey.Format("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s", (LPCSTR)guid);
RegOpenKeyExA(HKEY_LOCAL_MACHINE, strSubKey, 0, KEY_QUERY_VALUE, &hKey);
if (NULL != hKey)
{
CHAR szData[MAX_PATH] = { 0 };
DWORD cbData = MAX_PATH;
if (ERROR_SUCCESS == RegQueryValueExA(hKey, "InstallLocation", NULL, NULL, (LPBYTE)szData, &cbData))
{
strInstallLoc = szData;
}
RegCloseKey(hKey);
}
return strInstallLoc;
}
static CStringA GetUninstallString(const CStringA &guid)
{
CStringA strUninstall;
HKEY hKey = NULL;
CStringA strSubKey;
strSubKey.Format("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\%s", (LPCSTR)guid);
RegOpenKeyExA(HKEY_LOCAL_MACHINE, strSubKey, 0, KEY_QUERY_VALUE, &hKey);
if (NULL != hKey)
{
CHAR szData[MAX_PATH] = { 0 };
DWORD cbData = MAX_PATH;
if (ERROR_SUCCESS == RegQueryValueExA(hKey, "UninstallString", NULL, NULL, (LPBYTE)szData, &cbData))
{
strUninstall = szData;
}
RegCloseKey(hKey);
}
return strUninstall;
}
static bool AppIsRun(const CStringA &guid, const CStringA &appName)
{
CStringA strInstallLoc = GetInstallLocation(guid);
if (strInstallLoc.IsEmpty())
{
return false;
}
CStringW strAppPath2(strInstallLoc);
CStringW strAppName2(appName);
bool ret = false;
HANDLE hSnapshot = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnapshot != INVALID_HANDLE_VALUE)
{
PROCESSENTRY32 pe;
pe.dwSize = sizeof(PROCESSENTRY32);
BOOL bFindFirstProcess = ::Process32First(hSnapshot, &pe);
if (bFindFirstProcess)
{
do
{
WCHAR exeFullPath[1024] = { 0 };
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pe.th32ProcessID);
if (NULL != hProcess)
{
::GetModuleFileNameExW(hProcess, NULL, exeFullPath, 1024);
::CloseHandle(hProcess);
}
CStringW strExeFullPath(exeFullPath);
int pos = strExeFullPath.ReverseFind('\\');
if (-1 != pos)
{
CStringW strExeName = strExeFullPath.Right(strExeFullPath.GetLength() - pos - 1);
strExeFullPath.MakeLower();
strAppPath2.MakeLower();
if (0 == _wcsicmp(strExeName, strAppName2) && NULL != wcsstr(strExeFullPath, strAppPath2))
{
ret = true;
break;
}
}
} while (::Process32Next(hSnapshot, &pe));
}
::CloseHandle(hSnapshot);
}
return ret;
}
static int UninstallApp(const CStringA &guid)
{
CStringA strUninstall = GetUninstallString(guid);
if (strUninstall.IsEmpty())
{
return 0;
}
int ret = 1;
std::vector<CStringA> cmdList;
SplitString(strUninstall, ' ', cmdList);
if (!cmdList.empty())
{
CStringA exePath;
RemoveQuotes(cmdList[0], exePath);
int pos = exePath.ReverseFind('\\');
if (-1 == pos)
pos = exePath.ReverseFind('/');
if (-1 != pos)
{
CStringA exeDir = exePath.Left(pos + 1);
CStringA exeName = exePath.Right(exePath.GetLength() - pos - 1);
CHAR tmpPath[MAX_PATH] = { 0 };
GetTempPathA(MAX_PATH, tmpPath);
if (tmpPath[strlen(tmpPath) - 1] != '\\')
strcat_s(tmpPath, "\\");
CStringA tmpDir;
tmpDir.Format("%s{72A421E1-88A8-4D5C-97FA-F76B5B8A05E8}\\", tmpPath);
SHCreateDirectoryExA(NULL, tmpDir, NULL);
CopyFileA(exeDir + exeName, tmpDir + exeName, FALSE);
CopyFileA(exeDir + "ISSetup.dll", tmpDir + "ISSetup.dll", FALSE);
CopyFileA(exeDir + "0x0804.ini", tmpDir + "0x0804.ini", FALSE);
CopyFileA(exeDir + "Setup.ilg", tmpDir + "Setup.ilg", FALSE);
CopyFileA(exeDir + "setup.ini", tmpDir + "setup.ini", FALSE);
PROCESS_INFORMATION ProcessInfo;
STARTUPINFOA StartupInfo;
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof(StartupInfo);
char command[256];
sprintf_s(command, "%s%s -l0x0804 -removeonly", (LPCSTR)tmpDir, (LPCSTR)exeName);
if (CreateProcessA(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo))
{
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
CStringA strUninstall = GetUninstallString(guid);
if (strUninstall.IsEmpty())
{
ret = 0;
}
}
}
}
return ret;
}
static int UninstallDriver(const CStringA &guid)
{
CStringA strUninstall = GetUninstallString(guid);
if (strUninstall.IsEmpty())
{
return 0;
}
int ret = 1;
PROCESS_INFORMATION ProcessInfo;
STARTUPINFOA StartupInfo;
ZeroMemory(&StartupInfo, sizeof(StartupInfo));
StartupInfo.cb = sizeof(StartupInfo);
char command[256];
sprintf_s(command, "MsiExec.exe /x %s", (LPCSTR)guid);
if (CreateProcessA(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInfo))
{
WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
CloseHandle(ProcessInfo.hThread);
CloseHandle(ProcessInfo.hProcess);
CStringA strUninstall = GetUninstallString(guid);
if (strUninstall.IsEmpty())
{
ret = 0;
}
}
return ret;
}
static BOOL DeleteDirectory(LPCSTR lpszDir)
{
if (NULL == lpszDir || '\0' == lpszDir[0])
{
return FALSE;
}
if (!PathFileExistsA(lpszDir))
{
return FALSE;
}
WIN32_FIND_DATAA wfd = { 0 };
CHAR szFile[MAX_PATH] = { 0 };
CHAR szDelDir[MAX_PATH] = { 0 };
lstrcpyA(szDelDir, lpszDir);
if (lpszDir[lstrlenA(lpszDir) - 1] != L'\\')
{
_snprintf_s(szDelDir, _countof(szDelDir) - 1, "%s\\", lpszDir);
}
else
{
strncpy_s(szDelDir, lpszDir, _countof(szDelDir) - 1);
}
_snprintf_s(szFile, _countof(szFile) - 1, "%s*.*", szDelDir);
HANDLE hFindFile = FindFirstFileA(szFile, &wfd);
if (INVALID_HANDLE_VALUE == hFindFile)
{
return FALSE;
}
do
{
if (lstrcmpiA(wfd.cFileName, ".") == 0 || lstrcmpiA(wfd.cFileName, "..") == 0)
{
continue;
}
_snprintf_s(szFile, _countof(szFile) - 1, "%s%s", szDelDir, wfd.cFileName);
if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
DeleteDirectory(szFile);
}
else
{
DeleteFileA(szFile);
}
} while (FindNextFileA(hFindFile, &wfd));
FindClose(hFindFile);
RemoveDirectoryA(szDelDir);
return TRUE;
}
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
CStringW strCmdLine(lpCmdLine);
CStringA strAppGuid, strAppName;
if (-1 != strCmdLine.Find(L"OEM_HANWANG"))
{
strAppGuid = "InstallShield_{D6F0C80E-A058-485D-AA12-49D0656EC2BE}";
strAppName = "HanvonScan.exe";
}
else if (-1 != strCmdLine.Find(L"OEM_LISICHENG"))
{
strAppGuid = "InstallShield_{EA98728C-9793-4B3B-8D6C-3FAE94648972}";
strAppName = "LanxumScan.exe";
}
else if (-1 != strCmdLine.Find(L"OEM_CANGTIAN"))
{
return 0;
}
else if (-1 != strCmdLine.Find(L"OEM_ZHONGJING"))
{
return 0;
}
else if (-1 != strCmdLine.Find(L"OEM_ZIGUANG"))
{
return 0;
}
else if (-1 != strCmdLine.Find(L"OEM_NEUTRAL"))
{
return 0;
}
else if (-1 != strCmdLine.Find(L"OEM_DELI"))
{
return 0;
}
else
{
strAppGuid = "InstallShield_{6BE74035-CDC8-4CBF-937C-EBC08A9D6233}";
strAppName = "HuaGoScan.exe";
}
if (AppIsRun(strAppGuid, strAppName))
{
return 2;
}
CStringA strInstallPath = GetInstallLocation(strAppGuid);
int ret = UninstallApp(strAppGuid);
if (0 == ret)
{
DeleteDirectory(strInstallPath);
CHAR progPath[MAX_PATH];
SHGetSpecialFolderPathA(NULL, progPath, CSIDL_COMMON_PROGRAMS, FALSE);
CStringA strProgPath = progPath;
if (-1 != strCmdLine.Find(L"OEM_HANWANG"))
DeleteDirectory(strProgPath + "\\LanXum");
else if (-1 != strCmdLine.Find(L"OEM_LISICHENG"))
DeleteDirectory(strProgPath + "\\汉王科技股份有限公司");
else
DeleteDirectory(strProgPath + "\\HuaGaoChina");
CHAR desktopPath[MAX_PATH];
SHGetSpecialFolderPathA(NULL, desktopPath, CSIDL_COMMON_DESKTOPDIRECTORY, FALSE);
CStringA strDesktopPath = desktopPath;
if (-1 != strCmdLine.Find(L"OEM_HANWANG"))
DeleteFileA(strDesktopPath + "\\HanvonScan.lnk");
else if (-1 != strCmdLine.Find(L"OEM_LISICHENG"))
DeleteFileA(strDesktopPath + "\\LanxumScan.lnk");
else
DeleteFileA(strDesktopPath + "\\HuaGoScan.lnk");
CStringA strDriverGuid1, strDriverGuid2;
if (-1 != strCmdLine.Find(L"OEM_HANWANG"))
{
strDriverGuid1 = "{3D15346F-3E17-494E-B14B-5F221CD284B4}";
strDriverGuid2 = "{3D15346F-3E17-494E-B14B-5F221CD284B4}";
}
else if (-1 != strCmdLine.Find(L"OEM_LISICHENG"))
{
strDriverGuid1 = "{0C317880-F6D9-4293-92F2-0AA9CD260420}";
strDriverGuid2 = "{0C317880-F6D9-4293-92F2-0AA9CD260420}";
}
else
{
strDriverGuid1 = "{BDCDADB8-188F-4013-9591-BF231C595731}";
strDriverGuid2 = "{BD75DE93-2574-4EF8-B8DE-41023AB03C5B}";
}
ret = 1;
if (0 == UninstallDriver(strDriverGuid1) && 0 == UninstallDriver(strDriverGuid2))
ret = 0;
}
return ret;
}