// install.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。 // #include #include #include #include #include #include namespace fs = std::filesystem; #pragma comment( linker, "/subsystem:windows /entry:mainCRTStartup" ) std::string ws2s(const std::wstring& ws) { std::string curLocale = setlocale(LC_ALL, ""); const wchar_t* _Source = ws.c_str(); size_t _Dsize = wcstombs(NULL, _Source, 0) + 1; char* _Dest = new char[_Dsize]; memset(_Dest, 0, _Dsize); wcstombs(_Dest, _Source, _Dsize); std::string result = _Dest; delete[]_Dest; setlocale(LC_ALL, curLocale.c_str()); return result; } std::wstring s2ws(const std::string& s) { std::string curLocale = setlocale(LC_ALL, ""); const char* _Source = s.c_str(); size_t _Dsize = mbstowcs(NULL, _Source, 0) + 1; wchar_t* _Dest = new wchar_t[_Dsize]; wmemset(_Dest, 0, _Dsize); mbstowcs(_Dest, _Source, _Dsize); std::wstring result = _Dest; delete[]_Dest; setlocale(LC_ALL, curLocale.c_str()); return result; } bool RemoveDir(const char* szFileDir) { std::string strDir = szFileDir; if (strDir.at(strDir.length() - 1) != '\\') strDir += '\\'; WIN32_FIND_DATAA wfd; HANDLE hFind = FindFirstFileA((strDir + "*.*").c_str(), &wfd); if (hFind == INVALID_HANDLE_VALUE) return false; do { if (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { if (stricmp(wfd.cFileName, ".") != 0 && stricmp(wfd.cFileName, "..") != 0) RemoveDir((strDir + wfd.cFileName).c_str()); } else { DeleteFileA((strDir + wfd.cFileName).c_str()); } } while (FindNextFileA(hFind, &wfd)); FindClose(hFind); RemoveDirectoryA(szFileDir); return true; } void DeleteRegValue(HKEY rootKey, std::string regPath, std::string fileName) { char szKeyName[MAXBYTE] = { 0 }; HKEY hKey = NULL; if (ERROR_SUCCESS == RegOpenKeyExA(rootKey, regPath.c_str(), 0, KEY_ALL_ACCESS, &hKey)) { RegDeleteValueA(hKey, fileName.c_str()); RegCloseKey(hKey); } } void DeleteRegKey(HKEY rootKey, std::string subKey) { HKEY hKey; if (RegOpenKeyExA(rootKey, subKey.c_str(), 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) { while (true) { // 注册表项名称最长为251个有效字符 char subKeyName[251] = ""; if (RegEnumKeyA(hKey, 0, subKeyName, 251) != ERROR_SUCCESS) break; // 这里的2是路径分隔符"\"和结束符的占位 size_t fullPathLen = subKey.length() + 2 + strlen(subKeyName); char* fullPath = new char[fullPathLen]; strcpy(fullPath, subKey.c_str()); strcat(fullPath, "\\"); strcat(fullPath, subKeyName); DeleteRegKey(rootKey, fullPath); delete[] fullPath; } RegDeleteKeyA(rootKey, subKey.c_str()); RegCloseKey(hKey); } } std::string GetRegValue(HKEY rootKey, std::string strUrl, std::string strKey) { std::string strValue(""); HKEY hKeyResult = NULL; DWORD dwSize = 0; DWORD dwDataType = 0; //std::wstring wstrUrl = s2ws(strUrl); //std::wstring wstrKey = s2ws(strKey); //打开注册表 if (ERROR_SUCCESS == ::RegOpenKeyExA(rootKey, strUrl.c_str(), 0, KEY_QUERY_VALUE, &hKeyResult)) { // 获取缓存的长度dwSize及类型dwDataType ::RegQueryValueExA(hKeyResult, strKey.c_str(), 0, &dwDataType, NULL, &dwSize); switch (dwDataType) { case REG_MULTI_SZ: { //分配内存大小 BYTE* lpValue = new BYTE[dwSize]; //获取注册表中指定的键所对应的值 LONG lRet = ::RegQueryValueExA(hKeyResult, strKey.c_str(), 0, &dwDataType, lpValue, &dwSize); delete[] lpValue; break; } case REG_SZ: { //分配内存大小 char* lpValue = new char[dwSize]; memset(lpValue, 0, dwSize * sizeof(char)); //获取注册表中指定的键所对应的值 if (ERROR_SUCCESS == ::RegQueryValueExA(hKeyResult, strKey.c_str(), 0, &dwDataType, (LPBYTE)lpValue, &dwSize)) { strValue = std::string(lpValue); } delete[] lpValue; break; } default: break; } } //关闭注册表 ::RegCloseKey(hKeyResult); return strValue; } BOOL SetRegValue(HKEY rootKey, std::string Reg_Path, std::string file_name, std::string data) { HKEY hKey; if (ERROR_SUCCESS != RegOpenKeyExA(rootKey, Reg_Path.c_str(), 0, KEY_WRITE, &hKey)) { if (ERROR_SUCCESS != ::RegCreateKeyA(rootKey, Reg_Path.c_str(), &hKey)) { return false; } } if (ERROR_SUCCESS != RegSetValueExA(hKey, file_name.c_str(), 0, REG_SZ, (BYTE*)data.c_str(), (1 + data.length()))) { RegCloseKey(hKey); return FALSE; } RegCloseKey(hKey); return true; } void DeleteAppSelf() { char szCommandLine[MAX_PATH + 10] = { 0 }; SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); SetThreadPriority(GetCurrentProcess(), THREAD_PRIORITY_TIME_CRITICAL); SHChangeNotify(SHCNE_DELETE, SHCNF_PATH, _pgmptr, NULL); char szFilePath[MAX_PATH] = { 0 }; sprintf(szFilePath, R"(%s)", _pgmptr); sprintf(szCommandLine, "/c del /q %s", szFilePath); ShellExecuteA(NULL, "open", "cmd.exe", szCommandLine, NULL, SW_HIDE); ExitProcess(0); } void PrintfUseage() { std::cout << " -i \t\t 安装注册表" << std::endl; std::cout << " -u \t\t 卸载注册表" << std::endl; } void Install(std::string file_path) { SetRegValue(HKEY_CLASSES_ROOT, "webcamservice", "", "webcamservice Protocol"); SetRegValue(HKEY_CLASSES_ROOT, "webcamservice", "URL Protocol", "webcamservice Protocol"); SetRegValue(HKEY_CLASSES_ROOT, "webcamservice\\DefaultIcon", "", file_path); char path[MAX_PATH] = { 0 }; sprintf(path, R"(%s "%%1")", file_path.c_str()); SetRegValue(HKEY_CLASSES_ROOT, "webcamservice\\Shell\\Open\\command", "", path); //删除旧版本安装目录 //RemoveDir("C:\\WebCamService"); //DeleteRegKey(HKEY_CLASSES_ROOT, "webcamservice"); } void Uninstall(std::string file_dir) { auto remove_file = [&file_dir](std::string file_name) { std::string file_path = file_dir + std::string("\\") + file_name; remove(file_path.c_str()); }; DeleteRegKey(HKEY_CLASSES_ROOT, "webcamservice"); //remove_file("DeepCamNvrService.exe"); //DeleteAppSelf(); } std::string getCurrPath() { char chpath[MAX_PATH]; GetModuleFileNameA(NULL, (LPSTR)chpath, sizeof(chpath)); std::string path = std::string(chpath); int pos = path.find_last_of("\\"); if (pos != std::string::npos) { path = path.substr(0, pos); SetCurrentDirectoryA(path.c_str()); } return path; } int main(int argc, char* argv[]) { if (argc < 2) { PrintfUseage(); //getchar(); return 0; } std::string cmd = std::string(argv[1]); std::string curr_path= getCurrPath(); if (cmd.compare("-i") == 0) { DeleteRegKey(HKEY_CLASSES_ROOT, "webcamservice"); char file_path[256] = { 0 }; sprintf(file_path, "%s\\launcher.exe", curr_path.c_str()); Install(file_path); } else if (cmd.compare("-u") == 0) { Uninstall(curr_path); } else { PrintfUseage(); } //getchar(); return 0; }