diff --git a/WeaselSetup/InstallOptionsDlg.h b/WeaselSetup/InstallOptionsDlg.h index 219bf6a72..4a7ba6ecb 100644 --- a/WeaselSetup/InstallOptionsDlg.h +++ b/WeaselSetup/InstallOptionsDlg.h @@ -31,6 +31,42 @@ MSG_ID_CAP(info, idCap, uType); \ } +template +LSTATUS SetRegKeyValue(HKEY rootKey, + const wchar_t* subpath, + const wchar_t* key, + const T& value, + DWORD type, + bool disable_reg_redirect = false) { + HKEY hKey; + auto flag_wow64 = (disable_reg_redirect && is_wow64()) ? KEY_WOW64_64KEY : 0; + LSTATUS ret = + RegOpenKeyEx(rootKey, subpath, 0, KEY_ALL_ACCESS | flag_wow64, &hKey); + if (ret != ERROR_SUCCESS) { + ret = RegCreateKeyEx(rootKey, subpath, 0, NULL, 0, + KEY_ALL_ACCESS | flag_wow64, 0, &hKey, NULL); + if (ret != ERROR_SUCCESS) + return ret; + } + if (ret == ERROR_SUCCESS) { + DWORD dataSize; + const BYTE* dataPtr; + if constexpr (std::is_same::value) { + dataSize = (value.size() + 1) * sizeof(wchar_t); + dataPtr = reinterpret_cast(value.c_str()); + } else if constexpr (std::is_same::value) { + dataSize = (wcslen((wchar_t*)value) + 1) * sizeof(wchar_t); + dataPtr = reinterpret_cast(value); + } else { + dataSize = sizeof(T); + dataPtr = reinterpret_cast(&value); + } + ret = RegSetValueEx(hKey, key, 0, type, dataPtr, dataSize); + RegCloseKey(hKey); + } + return ret; +} + class InstallOptionsDialog : public CDialogImpl { public: enum { IDD = IDD_INSTALL_OPTIONS }; diff --git a/WeaselSetup/WeaselSetup.cpp b/WeaselSetup/WeaselSetup.cpp index 5e9378bbc..d9fe9861d 100644 --- a/WeaselSetup/WeaselSetup.cpp +++ b/WeaselSetup/WeaselSetup.cpp @@ -100,25 +100,15 @@ static int CustomInstall(bool installing) { if (0 != install(hant, silent, old_ime_support)) return 1; - ret = RegCreateKeyEx(HKEY_CURRENT_USER, KEY, 0, NULL, 0, KEY_ALL_ACCESS, 0, - &hKey, NULL); - if (FAILED(HRESULT_FROM_WIN32(ret))) { - MSG_ID_CAP(KEY, IDS_STR_INSTALL_FAILED, MB_ICONERROR | MB_OK); - return 1; - } - - ret = RegSetValueEx(hKey, L"RimeUserDir", 0, REG_SZ, - (const BYTE*)user_dir.c_str(), - (user_dir.length() + 1) * sizeof(WCHAR)); + ret = SetRegKeyValue(HKEY_CURRENT_USER, KEY, L"RimeUserDir", user_dir.c_str(), + REG_SZ, false); if (FAILED(HRESULT_FROM_WIN32(ret))) { MSG_BY_IDS(IDS_STR_ERR_WRITE_USER_DIR, IDS_STR_INSTALL_FAILED, MB_ICONERROR | MB_OK); return 1; } - - DWORD data = hant ? 1 : 0; - ret = RegSetValueEx(hKey, L"Hant", 0, REG_DWORD, (const BYTE*)&data, - sizeof(DWORD)); + ret = SetRegKeyValue(HKEY_CURRENT_USER, KEY, L"Hant", (hant ? 1 : 0), + REG_DWORD, false); if (FAILED(HRESULT_FROM_WIN32(ret))) { MSG_BY_IDS(IDS_STR_ERR_WRITE_HANT, IDS_STR_INSTALL_FAILED, MB_ICONERROR | MB_OK); @@ -151,24 +141,24 @@ static int Run(LPTSTR lpCmdLine) { if (uninstalling) return uninstall(silent); - auto setLanguage = [](const wchar_t* language) { - const WCHAR KEY[] = L"Software\\Rime\\Weasel"; - HKEY hKey; - LSTATUS ret = RegOpenKey(HKEY_CURRENT_USER, KEY, &hKey); - if (ret == ERROR_SUCCESS) { - ret = RegSetValueEx(hKey, L"Language", 0, REG_SZ, (const BYTE*)language, - (wcslen(language) + 1) * sizeof(wchar_t)); - RegCloseKey(hKey); - } - return ret; - }; - if (!wcscmp(L"/ls", lpCmdLine)) { - return setLanguage(L"chs"); + return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", + L"Language", L"chs", REG_SZ); } else if (!wcscmp(L"/lt", lpCmdLine)) { - return setLanguage(L"cht"); + return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", + L"Language", L"cht", REG_SZ); } else if (!wcscmp(L"/le", lpCmdLine)) { - return setLanguage(L"eng"); + return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", + L"Language", L"eng", REG_SZ); + } + + if (!wcscmp(L"/eu", lpCmdLine)) { + return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel\\Updates", + L"CheckForUpdates", L"1", REG_SZ); + } + if (!wcscmp(L"/du", lpCmdLine)) { + return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel\\Updates", + L"CheckForUpdates", L"0", REG_SZ); } bool hans = !wcscmp(L"/s", lpCmdLine); diff --git a/WeaselSetup/imesetup.cpp b/WeaselSetup/imesetup.cpp index e93363b34..ed48aea99 100644 --- a/WeaselSetup/imesetup.cpp +++ b/WeaselSetup/imesetup.cpp @@ -33,6 +33,10 @@ static const GUID c_guidProfile = { #define ILOT_UNINSTALL 0x00000001 typedef HRESULT(WINAPI* PTF_INSTALLLAYOUTORTIP)(LPCWSTR psz, DWORD dwFlags); +#define WEASEL_WER_KEY \ + L"SOFTWARE\\Microsoft\\Windows\\Windows Error " \ + L"Reporting\\LocalDumps\\WeaselServer.exe" + BOOL copy_file(const std::wstring& src, const std::wstring& dest) { BOOL ret = CopyFile(src.c_str(), dest.c_str(), FALSE); if (!ret) { @@ -539,11 +543,6 @@ int register_text_service(const std::wstring& tsf_path, return 0; } -void executeCommandA(const std::string& command) { - ShellExecuteA(NULL, "open", "cmd.exe", ("/C " + command).c_str(), NULL, - SW_HIDE); -} - int install(bool hant, bool silent, bool old_ime_support) { std::wstring ime_src_path; int retval = 0; @@ -555,24 +554,14 @@ int install(bool hant, bool silent, bool old_ime_support) { ®ister_text_service); // 写注册表 - HKEY hKey; - LSTATUS ret = RegCreateKeyEx(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY, 0, NULL, 0, - KEY_ALL_ACCESS, 0, &hKey, NULL); - if (FAILED(HRESULT_FROM_WIN32(ret))) { - MSG_NOT_SILENT_ID_CAP(silent, WEASEL_REG_KEY, IDS_STR_INSTALL_FAILED, - MB_ICONERROR | MB_OK); - return 1; - } - WCHAR drive[_MAX_DRIVE]; WCHAR dir[_MAX_DIR]; _wsplitpath_s(ime_src_path.c_str(), drive, _countof(drive), dir, _countof(dir), NULL, 0, NULL, 0); std::wstring rootDir = std::wstring(drive) + dir; rootDir.pop_back(); - ret = RegSetValueEx(hKey, L"WeaselRoot", 0, REG_SZ, - (const BYTE*)rootDir.c_str(), - (rootDir.length() + 1) * sizeof(WCHAR)); + auto ret = SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY, L"WeaselRoot", + rootDir.c_str(), REG_SZ); if (FAILED(HRESULT_FROM_WIN32(ret))) { MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRWRITEWEASELROOT, IDS_STR_INSTALL_FAILED, MB_ICONERROR | MB_OK); @@ -580,16 +569,14 @@ int install(bool hant, bool silent, bool old_ime_support) { } const std::wstring executable = L"WeaselServer.exe"; - ret = RegSetValueEx(hKey, L"ServerExecutable", 0, REG_SZ, - (const BYTE*)executable.c_str(), - (executable.length() + 1) * sizeof(WCHAR)); + ret = SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY, L"ServerExecutable", + executable.c_str(), REG_SZ); if (FAILED(HRESULT_FROM_WIN32(ret))) { MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRREGIMEWRITESVREXE, IDS_STR_INSTALL_FAILED, MB_ICONERROR | MB_OK); return 1; } - RegCloseKey(hKey); // InstallLayoutOrTip // https://learn.microsoft.com/zh-cn/windows/win32/tsf/installlayoutortip // example in ref page not right with "*PTF_ INSTALLLAYOUTORTIP" @@ -608,50 +595,20 @@ int install(bool hant, bool silent, bool old_ime_support) { FreeLibrary(hInputDLL); } - // write WER register - if (is_wow64()) { - PVOID OldValue = NULL; - if (Wow64DisableWow64FsRedirection(&OldValue) == FALSE) { - MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRCANCELFSREDIRECT, - IDS_STR_UNINSTALL_FAILED, MB_ICONERROR | MB_OK); - return 1; - } - } // https://learn.microsoft.com/zh-cn/windows/win32/wer/collecting-user-mode-dumps - const std::string dmpPath = WeaselLogPath().string(); - executeCommandA( - "REG ADD \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows " - "Error Reporting\\LocalDumps\\WeaselServer.exe\" /f"); - // dump file path - executeCommandA( - "REG ADD \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows " - "Error Reporting\\LocalDumps\\WeaselServer.exe\" /t REG_SZ /v DumpFolder " - "/d " + - dmpPath + " /f"); + const std::wstring dmpPathW = WeaselLogPath().wstring(); + // DumpFolder + SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_WER_KEY, L"DumpFolder", + dmpPathW.c_str(), REG_SZ, true); // dump type 0 - executeCommandA( - "REG ADD \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows " - "Error Reporting\\LocalDumps\\WeaselServer.exe\" /t REG_DWORD /v " - "DumpType /d 0 /f"); + SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_WER_KEY, L"DumpType", 0, REG_DWORD, + true); // CustomDumpFlags, MiniDumpNormal - executeCommandA( - "REG ADD \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows " - "Error Reporting\\LocalDumps\\WeaselServer.exe\" /t REG_DWORD /v " - "CustomDumpFlags /d 0 /f"); + SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_WER_KEY, L"CustomDumpFlags", 0, + REG_DWORD, true); // maximium dump count 10 - executeCommandA( - "REG ADD \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows " - "Error Reporting\\LocalDumps\\WeaselServer.exe\" /t REG_DWORD /v " - "DumpCount /d 10 /f"); - - if (is_wow64()) { - PVOID OldValue = NULL; - if (Wow64RevertWow64FsRedirection(&OldValue) == FALSE) { - MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRRECOVERFSREDIRECT, - IDS_STR_UNINSTALL_FAILED, MB_ICONERROR | MB_OK); - return 1; - } - } + SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_WER_KEY, L"DumpCount", 10, + REG_DWORD, true); if (retval) return 1; @@ -699,26 +656,12 @@ int uninstall(bool silent) { RegDeleteKey(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY); RegDeleteKey(HKEY_LOCAL_MACHINE, RIME_REG_KEY); - // delete WER register - if (is_wow64()) { - PVOID OldValue = NULL; - if (Wow64DisableWow64FsRedirection(&OldValue) == FALSE) { - MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRCANCELFSREDIRECT, - IDS_STR_UNINSTALL_FAILED, MB_ICONERROR | MB_OK); - return 1; - } - } - executeCommandA( - "REG DELETE \"HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows " - "Error Reporting\\LocalDumps\\WeaselServer.exe\" /f"); - if (is_wow64()) { - PVOID OldValue = NULL; - if (Wow64RevertWow64FsRedirection(&OldValue) == FALSE) { - MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRRECOVERFSREDIRECT, - IDS_STR_UNINSTALL_FAILED, MB_ICONERROR | MB_OK); - return 1; - } - } + // delete WER register, + // "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows\\Windows Error + // Reporting\\LocalDumps\\WeaselServer.exe" no WOW64 redirect + + auto flag_wow64 = is_wow64() ? KEY_WOW64_64KEY : 0; + RegDeleteKeyEx(HKEY_LOCAL_MACHINE, WEASEL_WER_KEY, flag_wow64, 0); if (retval) return 1;