diff --git a/WeaselSetup/InstallOptionsDlg.cpp b/WeaselSetup/InstallOptionsDlg.cpp deleted file mode 100644 index 54fce46c8..000000000 --- a/WeaselSetup/InstallOptionsDlg.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "stdafx.h" -#include "InstallOptionsDlg.h" -#include -#include -#pragma comment(lib, "Shell32.lib") - -int uninstall(bool silent); - -InstallOptionsDialog::InstallOptionsDialog() - : installed(false), hant(false), user_dir() {} - -InstallOptionsDialog::~InstallOptionsDialog() {} - -LRESULT InstallOptionsDialog::OnInitDialog(UINT, WPARAM, LPARAM, BOOL&) { - cn_.Attach(GetDlgItem(IDC_RADIO_CN)); - tw_.Attach(GetDlgItem(IDC_RADIO_TW)); - remove_.Attach(GetDlgItem(IDC_REMOVE)); - default_dir_.Attach(GetDlgItem(IDC_RADIO_DEFAULT_DIR)); - custom_dir_.Attach(GetDlgItem(IDC_RADIO_CUSTOM_DIR)); - dir_.Attach(GetDlgItem(IDC_EDIT_DIR)); - - CheckRadioButton(IDC_RADIO_CN, IDC_RADIO_TW, - (hant ? IDC_RADIO_TW : IDC_RADIO_CN)); - CheckRadioButton( - IDC_RADIO_DEFAULT_DIR, IDC_RADIO_CUSTOM_DIR, - (user_dir.empty() ? IDC_RADIO_DEFAULT_DIR : IDC_RADIO_CUSTOM_DIR)); - dir_.SetWindowTextW(user_dir.c_str()); - - cn_.EnableWindow(!installed); - tw_.EnableWindow(!installed); - remove_.EnableWindow(installed); - dir_.EnableWindow(user_dir.empty() ? FALSE : TRUE); - - button_custom_dir_.Attach(GetDlgItem(IDC_BUTTON_CUSTOM_DIR)); - button_custom_dir_.EnableWindow(user_dir.empty() ? FALSE : TRUE); - - ok_.Attach(GetDlgItem(IDOK)); - if (installed) { - CString str; - str.LoadStringW(IDS_STRING_MODIFY); - ok_.SetWindowTextW(str); - } - - ime_.Attach(GetDlgItem(IDC_CHECK_INSTIME)); - if (installed) - ime_.EnableWindow(FALSE); - - CenterWindow(); - return 0; -} - -LRESULT InstallOptionsDialog::OnClose(UINT, WPARAM, LPARAM, BOOL&) { - EndDialog(IDCANCEL); - return 0; -} - -LRESULT InstallOptionsDialog::OnOK(WORD, WORD code, HWND, BOOL&) { - hant = (IsDlgButtonChecked(IDC_RADIO_TW) == BST_CHECKED); - old_ime_support = (IsDlgButtonChecked(IDC_CHECK_INSTIME) == BST_CHECKED); - if (IsDlgButtonChecked(IDC_RADIO_CUSTOM_DIR) == BST_CHECKED) { - CStringW text; - dir_.GetWindowTextW(text); - user_dir = text; - } else { - user_dir.clear(); - } - EndDialog(IDOK); - return 0; -} - -LRESULT InstallOptionsDialog::OnRemove(WORD, WORD code, HWND, BOOL&) { - const bool non_silent = false; - uninstall(non_silent); - installed = false; - ime_.EnableWindow(!installed); - CString str; - str.LoadStringW(IDS_STRING_INSTALL); - ok_.SetWindowTextW(str); - cn_.EnableWindow(!installed); - tw_.EnableWindow(!installed); - remove_.EnableWindow(installed); - return 0; -} - -LRESULT InstallOptionsDialog::OnUseDefaultDir(WORD, WORD code, HWND, BOOL&) { - dir_.EnableWindow(FALSE); - dir_.SetWindowTextW(L""); - button_custom_dir_.EnableWindow(FALSE); - return 0; -} - -LRESULT InstallOptionsDialog::OnUseCustomDir(WORD, WORD code, HWND, BOOL&) { - CShellFileOpenDialog fileOpenDlg( - NULL, FOS_FORCEFILESYSTEM | FOS_PATHMUSTEXIST | FOS_PICKFOLDERS); - CStringW text; - dir_.GetWindowTextW(text); - if (!text.IsEmpty()) { - PIDLIST_ABSOLUTE pidl; - HRESULT hr = SHParseDisplayName(text, NULL, &pidl, 0, NULL); - if (SUCCEEDED(hr)) { - IShellItem* psi; - hr = SHCreateShellItem(NULL, NULL, pidl, &psi); - if (SUCCEEDED(hr)) { - fileOpenDlg.GetPtr()->SetFolder(psi); - psi->Release(); - } - CoTaskMemFree(pidl); - } - } - if (fileOpenDlg.DoModal(m_hWnd) == IDOK) { - CComPtr psi; - if (SUCCEEDED(fileOpenDlg.GetPtr()->GetResult(&psi))) { - LPWSTR path; - if (SUCCEEDED(psi->GetDisplayName(SIGDN_FILESYSPATH, &path))) { - dir_.SetWindowTextW(path); - CoTaskMemFree(path); - } - } - } - ok_.SetFocus(); - return 0; -} diff --git a/WeaselSetup/InstallOptionsDlg.h b/WeaselSetup/InstallOptionsDlg.h deleted file mode 100644 index 4a7ba6ecb..000000000 --- a/WeaselSetup/InstallOptionsDlg.h +++ /dev/null @@ -1,109 +0,0 @@ -#pragma once - -#include "resource.h" -#include - -#define MSG_BY_IDS(idInfo, idCap, uType) \ - { \ - CString info, cap; \ - info.LoadStringW(idInfo); \ - cap.LoadStringW(idCap); \ - LANGID langID = GetThreadUILanguage(); \ - MessageBoxExW(NULL, info, cap, uType, langID); \ - } - -#define MSG_ID_CAP(info, idCap, uType) \ - { \ - CString cap; \ - cap.LoadStringW(idCap); \ - LANGID langID = GetThreadUILanguage(); \ - MessageBoxExW(NULL, info, cap, uType, langID); \ - } - -#define MSG_NOT_SILENT_BY_IDS(silent, idInfo, idCap, uType) \ - { \ - if (!silent) \ - MSG_BY_IDS(idInfo, idCap, uType); \ - } -#define MSG_NOT_SILENT_ID_CAP(silent, info, idCap, uType) \ - { \ - if (!silent) \ - 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 }; - - InstallOptionsDialog(); - ~InstallOptionsDialog(); - - bool installed; - bool hant; - bool old_ime_support; - std::wstring user_dir; - - protected: - BEGIN_MSG_MAP(InstallOptionsDialog) - MESSAGE_HANDLER(WM_INITDIALOG, OnInitDialog) - MESSAGE_HANDLER(WM_CLOSE, OnClose) - COMMAND_ID_HANDLER(IDOK, OnOK) - COMMAND_ID_HANDLER(IDC_REMOVE, OnRemove) - COMMAND_ID_HANDLER(IDC_RADIO_DEFAULT_DIR, OnUseDefaultDir) - COMMAND_ID_HANDLER(IDC_RADIO_CUSTOM_DIR, OnUseCustomDir) - COMMAND_ID_HANDLER(IDC_BUTTON_CUSTOM_DIR, OnUseCustomDir) - END_MSG_MAP() - - LRESULT OnInitDialog(UINT, WPARAM, LPARAM, BOOL&); - LRESULT OnClose(UINT, WPARAM, LPARAM, BOOL&); - LRESULT OnOK(WORD, WORD code, HWND, BOOL&); - LRESULT OnRemove(WORD, WORD code, HWND, BOOL&); - LRESULT OnUseDefaultDir(WORD, WORD code, HWND, BOOL&); - LRESULT OnUseCustomDir(WORD, WORD code, HWND, BOOL&); - - CButton cn_; - CButton tw_; - CButton remove_; - CButton default_dir_; - CButton custom_dir_; - CButton ok_; - CButton ime_; - CButton button_custom_dir_; - CEdit dir_; -}; diff --git a/WeaselSetup/WeaselSetup.cpp b/WeaselSetup/WeaselSetup.cpp deleted file mode 100644 index 43286ecfb..000000000 --- a/WeaselSetup/WeaselSetup.cpp +++ /dev/null @@ -1,251 +0,0 @@ -// WeaselSetup.cpp : main source file for WeaselSetup.exe -// - -#include "stdafx.h" - -#include "resource.h" -#include "WeaselUtility.h" -#include - -#include "InstallOptionsDlg.h" - -#include -#pragma comment(lib, "Shcore.lib") -CAppModule _Module; - -static int Run(LPTSTR lpCmdLine); -static bool IsProcAdmin(); -static int RestartAsAdmin(LPTSTR lpCmdLine); - -int WINAPI _tWinMain(HINSTANCE hInstance, - HINSTANCE /*hPrevInstance*/, - LPTSTR lpstrCmdLine, - int /*nCmdShow*/) { - HRESULT hRes = ::CoInitialize(NULL); - ATLASSERT(SUCCEEDED(hRes)); - - AtlInitCommonControls( - ICC_BAR_CLASSES); // add flags to support other controls - - hRes = _Module.Init(NULL, hInstance); - ATLASSERT(SUCCEEDED(hRes)); - - LANGID langId = get_language_id(); - SetThreadUILanguage(langId); - SetThreadLocale(langId); - - int nRet = Run(lpstrCmdLine); - - _Module.Term(); - ::CoUninitialize(); - - return nRet; -} -int install(bool hant, bool silent, bool old_ime_support); -int uninstall(bool silent); -bool has_installed(); - -static std::wstring install_dir() { - WCHAR exe_path[MAX_PATH] = {0}; - GetModuleFileNameW(GetModuleHandle(NULL), exe_path, _countof(exe_path)); - std::wstring dir(exe_path); - size_t pos = dir.find_last_of(L"\\"); - dir.resize(pos); - return dir; -} - -static int CustomInstall(bool installing) { - bool hant = false; - bool silent = false; - bool old_ime_support = false; - std::wstring user_dir; - - const WCHAR KEY[] = L"Software\\Rime\\Weasel"; - HKEY hKey; - LSTATUS ret = RegOpenKey(HKEY_CURRENT_USER, KEY, &hKey); - if (ret == ERROR_SUCCESS) { - WCHAR value[MAX_PATH]; - DWORD len = sizeof(value); - DWORD type = 0; - DWORD data = 0; - ret = - RegQueryValueEx(hKey, L"RimeUserDir", NULL, &type, (LPBYTE)value, &len); - if (ret == ERROR_SUCCESS && type == REG_SZ) { - user_dir = value; - } - len = sizeof(data); - ret = RegQueryValueEx(hKey, L"Hant", NULL, &type, (LPBYTE)&data, &len); - if (ret == ERROR_SUCCESS && type == REG_DWORD) { - hant = (data != 0); - if (installing) - silent = true; - } - RegCloseKey(hKey); - } - bool _has_installed = has_installed(); - if (!silent) { - InstallOptionsDialog dlg; - dlg.installed = _has_installed; - dlg.hant = hant; - dlg.user_dir = user_dir; - if (IDOK != dlg.DoModal()) { - if (!installing) - return 1; // aborted by user - } else { - hant = dlg.hant; - user_dir = dlg.user_dir; - old_ime_support = dlg.old_ime_support; - _has_installed = dlg.installed; - } - } - if (!_has_installed) - if (0 != install(hant, silent, old_ime_support)) - return 1; - - 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; - } - 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); - return 1; - } - if (_has_installed) { - std::wstring dir(install_dir()); - std::thread th([dir]() { - ShellExecuteW(NULL, NULL, (dir + L"\\WeaselServer.exe").c_str(), L"/q", - NULL, SW_SHOWNORMAL); - Sleep(500); - ShellExecuteW(NULL, NULL, (dir + L"\\WeaselServer.exe").c_str(), L"", - NULL, SW_SHOWNORMAL); - Sleep(500); - ShellExecuteW(NULL, NULL, (dir + L"\\WeaselDeployer.exe").c_str(), - L"/deploy", NULL, SW_SHOWNORMAL); - }); - th.detach(); - MSG_BY_IDS(IDS_STR_MODIFY_SUCCESS_INFO, IDS_STR_MODIFY_SUCCESS_CAP, - MB_ICONINFORMATION | MB_OK); - } - - return 0; -} - -LPCTSTR GetParamByPrefix(LPCTSTR lpCmdLine, LPCTSTR prefix) { - return (wcsncmp(lpCmdLine, prefix, wcslen(prefix)) == 0) - ? (lpCmdLine + wcslen(prefix)) - : 0; -} - -static int Run(LPTSTR lpCmdLine) { - constexpr bool silent = true; - constexpr bool old_ime_support = false; - bool uninstalling = !wcscmp(L"/u", lpCmdLine); - if (uninstalling) { - if (IsProcAdmin()) - return uninstall(silent); - else - return RestartAsAdmin(lpCmdLine); - } - - if (auto res = GetParamByPrefix(lpCmdLine, L"/userdir:")) { - return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", - L"RimeUserDir", res, REG_SZ); - } - - if (!wcscmp(L"/ls", lpCmdLine)) { - return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", - L"Language", L"chs", REG_SZ); - } else if (!wcscmp(L"/lt", lpCmdLine)) { - return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", - L"Language", L"cht", REG_SZ); - } else if (!wcscmp(L"/le", lpCmdLine)) { - 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); - } - - if (!wcscmp(L"/toggleime", lpCmdLine)) { - return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", - L"ToggleImeOnOpenClose", L"yes", REG_SZ); - } - if (!wcscmp(L"/toggleascii", lpCmdLine)) { - return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", - L"ToggleImeOnOpenClose", L"no", REG_SZ); - } - if (!wcscmp(L"/testing", lpCmdLine)) { - return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", - L"UpdateChannel", L"testing", REG_SZ); - } - if (!wcscmp(L"/release", lpCmdLine)) { - return SetRegKeyValue(HKEY_CURRENT_USER, L"Software\\Rime\\weasel", - L"UpdateChannel", L"release", REG_SZ); - } - - if (!IsProcAdmin()) { - return RestartAsAdmin(lpCmdLine); - } - - bool hans = !wcscmp(L"/s", lpCmdLine); - if (hans) - return install(false, silent, old_ime_support); - bool hant = !wcscmp(L"/t", lpCmdLine); - if (hant) - return install(true, silent, old_ime_support); - bool installing = !wcscmp(L"/i", lpCmdLine); - return CustomInstall(installing); -} - -// https://learn.microsoft.com/zh-cn/windows/win32/api/securitybaseapi/nf-securitybaseapi-checktokenmembership -bool IsProcAdmin() { - BOOL b = FALSE; - SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY; - PSID AdministratorsGroup; - b = AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, - &AdministratorsGroup); - - if (b) { - if (!CheckTokenMembership(NULL, AdministratorsGroup, &b)) { - b = FALSE; - } - FreeSid(AdministratorsGroup); - } - - return (b); -} - -int RestartAsAdmin(LPTSTR lpCmdLine) { - SHELLEXECUTEINFO execInfo{0}; - TCHAR path[MAX_PATH]; - GetModuleFileName(GetModuleHandle(NULL), path, _countof(path)); - execInfo.lpFile = path; - execInfo.lpParameters = lpCmdLine; - execInfo.lpVerb = _T("runas"); - execInfo.cbSize = sizeof(execInfo); - execInfo.nShow = SW_SHOWNORMAL; - execInfo.fMask = SEE_MASK_NOASYNC | SEE_MASK_NOCLOSEPROCESS; - execInfo.hwnd = NULL; - execInfo.hProcess = NULL; - if (::ShellExecuteEx(&execInfo) && execInfo.hProcess != NULL) { - ::WaitForSingleObject(execInfo.hProcess, INFINITE); - DWORD dwExitCode = 0; - ::GetExitCodeProcess(execInfo.hProcess, &dwExitCode); - ::CloseHandle(execInfo.hProcess); - return dwExitCode; - } - return -1; -} diff --git a/WeaselSetup/WeaselSetup.h b/WeaselSetup/WeaselSetup.h deleted file mode 100644 index 99d30f5f1..000000000 --- a/WeaselSetup/WeaselSetup.h +++ /dev/null @@ -1 +0,0 @@ -// WeaselSetup.h diff --git a/WeaselSetup/WeaselSetup.ico b/WeaselSetup/WeaselSetup.ico deleted file mode 100644 index b2a7c748e..000000000 Binary files a/WeaselSetup/WeaselSetup.ico and /dev/null differ diff --git a/WeaselSetup/WeaselSetup.rc b/WeaselSetup/WeaselSetup.rc deleted file mode 100644 index 5a67a1582..000000000 Binary files a/WeaselSetup/WeaselSetup.rc and /dev/null differ diff --git a/WeaselSetup/WeaselSetup.vcxproj b/WeaselSetup/WeaselSetup.vcxproj deleted file mode 100644 index a141fc515..000000000 --- a/WeaselSetup/WeaselSetup.vcxproj +++ /dev/null @@ -1,160 +0,0 @@ - - - - - Debug - Win32 - - - Release - Win32 - - - - 17.0 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095} - WeaselSetup - - - - - Application - true - $(PLATFORM_TOOLSET) - Unicode - - - Application - false - true - $(PLATFORM_TOOLSET) - Unicode - - - - - - - - - - - - - - - false - $(SolutionDir)output\ - $(SolutionDir)msbuild\$(Configuration)\$(Platform)\$(ProjectName)\ - - - true - $(SolutionDir)output\ - $(SolutionDir)msbuild\$(Configuration)\$(Platform)\$(ProjectName)\ - - - - Use - Level3 - MultiThreaded - Sync - - WIN32;_WINDOWS;STRICT;NDEBUG;%(PreprocessorDefinitions) - stdcpp17 - $(SolutionDir)include;$(BOOST_ROOT) - true - - - Windows - Imm32.lib;Kernel32.lib;%(AdditionalDependencies) - $(SolutionDir)output\$(ProjectName)$(TargetExt) - AsInvoker - UseLinkTimeCodeGeneration - - - 0x7804 - $(IntDir);$(SolutionDir)\include\wtl - NDEBUG;%(PreprocessorDefinitions) - - - false - Win32 - NDEBUG;%(PreprocessorDefinitions) - WeaselSetup.h - WeaselSetup_i.c - WeaselSetup_p.c - true - $(IntDir)/WeaselSetup.tlb - - - - PerMonitorHighDPIAware - - - - - Use - Level3 - MultiThreadedDebug - EditAndContinue - EnableFastChecks - Disabled - WIN32;_WINDOWS;STRICT;_DEBUG;%(PreprocessorDefinitions) - stdcpp17 - $(SolutionDir)include;$(BOOST_ROOT) - - - - - Windows - true - Imm32.lib;Kernel32.lib;%(AdditionalDependencies) - $(SolutionDir)output\$(ProjectName)$(TargetExt) - AsInvoker - - - - - 0x7804 - $(IntDir);$(SolutionDir)\include\wtl - _DEBUG;%(PreprocessorDefinitions) - - - false - Win32 - _DEBUG;%(PreprocessorDefinitions) - WeaselSetup.h - WeaselSetup_i.c - WeaselSetup_p.c - true - $(IntDir)/WeaselSetup.tlb - - - - PerMonitorHighDPIAware - - - - - - - Create - Create - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/WeaselSetup/WeaselSetup.vcxproj.filters b/WeaselSetup/WeaselSetup.vcxproj.filters deleted file mode 100644 index 84e08d0b9..000000000 --- a/WeaselSetup/WeaselSetup.vcxproj.filters +++ /dev/null @@ -1,52 +0,0 @@ - - - - - {2df80f89-25ee-49a8-a0bf-2dd38ec3b0b2} - cpp;c;cxx;def;odl;idl;hpj;bat;asm - - - {30b9a326-3c70-4dd6-99a0-8fc6015e684b} - h;hpp;hxx;hm;inl;inc - - - {6ed053d1-845d-4449-a84b-43340151cc7c} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;jpg;jpeg;jpe;manifest - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - - - Header Files - - - Header Files - - - Header Files - - - - - Resource Files - - - - - Resource Files - - - \ No newline at end of file diff --git a/WeaselSetup/imesetup.cpp b/WeaselSetup/imesetup.cpp deleted file mode 100644 index ed48aea99..000000000 --- a/WeaselSetup/imesetup.cpp +++ /dev/null @@ -1,681 +0,0 @@ -#include "stdafx.h" -#include -#include -#include -#include -#include -#include -#include -#include "InstallOptionsDlg.h" - -// {A3F4CDED-B1E9-41EE-9CA6-7B4D0DE6CB0A} -static const GUID c_clsidTextService = { - 0xa3f4cded, - 0xb1e9, - 0x41ee, - {0x9c, 0xa6, 0x7b, 0x4d, 0xd, 0xe6, 0xcb, 0xa}}; - -// {3D02CAB6-2B8E-4781-BA20-1C9267529467} -static const GUID c_guidProfile = { - 0x3d02cab6, - 0x2b8e, - 0x4781, - {0xba, 0x20, 0x1c, 0x92, 0x67, 0x52, 0x94, 0x67}}; - -// if in the future, option hant is extended, maybe a function to generate this -// info is required -#define PSZTITLE_HANS \ - L"0804:{A3F4CDED-B1E9-41EE-9CA6-7B4D0DE6CB0A}{3D02CAB6-2B8E-4781-BA20-" \ - L"1C9267529467}" -#define PSZTITLE_HANT \ - L"0404:{A3F4CDED-B1E9-41EE-9CA6-7B4D0DE6CB0A}{3D02CAB6-2B8E-4781-BA20-" \ - L"1C9267529467}" -#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) { - for (int i = 0; i < 10; ++i) { - std::wstring old = dest + L".old." + std::to_wstring(i); - if (MoveFileEx(dest.c_str(), old.c_str(), MOVEFILE_REPLACE_EXISTING)) { - MoveFileEx(old.c_str(), NULL, MOVEFILE_DELAY_UNTIL_REBOOT); - break; - } - } - ret = CopyFile(src.c_str(), dest.c_str(), FALSE); - } - return ret; -} - -BOOL delete_file(const std::wstring& file) { - BOOL ret = DeleteFile(file.c_str()); - if (!ret) { - for (int i = 0; i < 10; ++i) { - std::wstring old = file + L".old." + std::to_wstring(i); - if (MoveFileEx(file.c_str(), old.c_str(), MOVEFILE_REPLACE_EXISTING)) { - MoveFileEx(old.c_str(), NULL, MOVEFILE_DELAY_UNTIL_REBOOT); - return TRUE; - } - } - } - return ret; -} - -typedef BOOL(WINAPI* PISWOW64P2)(HANDLE, USHORT*, USHORT*); -BOOL is_arm64_machine() { - PISWOW64P2 fnIsWow64Process2 = (PISWOW64P2)GetProcAddress( - GetModuleHandle(_T("kernel32.dll")), "IsWow64Process2"); - - if (fnIsWow64Process2 == NULL) { - return FALSE; - } - - USHORT processMachine; - USHORT nativeMachine; - - if (!fnIsWow64Process2(GetCurrentProcess(), &processMachine, - &nativeMachine)) { - return FALSE; - } - return nativeMachine == IMAGE_FILE_MACHINE_ARM64; -} - -typedef HRESULT(WINAPI* PISWOWGMS)(USHORT, BOOL*); -typedef UINT(WINAPI* PGSW64DIR2)(LPWSTR, UINT, WORD); -INT get_wow_arm32_system_dir(LPWSTR lpBuffer, UINT uSize) { - PISWOWGMS fnIsWow64GuestMachineSupported = (PISWOWGMS)GetProcAddress( - GetModuleHandle(_T("kernel32.dll")), "IsWow64GuestMachineSupported"); - PGSW64DIR2 fnGetSystemWow64Directory2W = (PGSW64DIR2)GetProcAddress( - GetModuleHandle(_T("kernelbase.dll")), "GetSystemWow64Directory2W"); - - if (fnIsWow64GuestMachineSupported == NULL || - fnGetSystemWow64Directory2W == NULL) { - return 0; - } - - BOOL supported; - if (fnIsWow64GuestMachineSupported(IMAGE_FILE_MACHINE_ARMNT, &supported) != - S_OK) { - return 0; - } - - if (!supported) { - return 0; - } - - return fnGetSystemWow64Directory2W(lpBuffer, uSize, IMAGE_FILE_MACHINE_ARMNT); -} - -typedef int (*ime_register_func)(const std::wstring& ime_path, - bool register_ime, - bool is_wow64, - bool is_wowarm, - bool hant, - bool silent); - -int install_ime_file(std::wstring& srcPath, - const std::wstring& ext, - bool hant, - bool silent, - ime_register_func func) { - WCHAR path[MAX_PATH]; - GetModuleFileNameW(GetModuleHandle(NULL), path, _countof(path)); - - std::wstring srcFileName = L"weasel"; - - srcFileName += ext; - WCHAR drive[_MAX_DRIVE]; - WCHAR dir[_MAX_DIR]; - _wsplitpath_s(path, drive, _countof(drive), dir, _countof(dir), NULL, 0, NULL, - 0); - srcPath = std::wstring(drive) + dir + srcFileName; - - GetSystemDirectoryW(path, _countof(path)); - std::wstring destPath = std::wstring(path) + L"\\weasel" + ext; - - int retval = 0; - // 复制 .dll/.ime 到系统目录 - if (!copy_file(srcPath, destPath)) { - MSG_NOT_SILENT_ID_CAP(silent, destPath.c_str(), IDS_STR_INSTALL_FAILED, - MB_ICONERROR | MB_OK); - return 1; - } - retval += func(destPath, true, false, false, hant, silent); - if (is_wow64()) { - PVOID OldValue = NULL; - // PW64DW64FR fnWow64DisableWow64FsRedirection = - // (PW64DW64FR)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), - // "Wow64DisableWow64FsRedirection"); PW64RW64FR - // fnWow64RevertWow64FsRedirection = - // (PW64RW64FR)GetProcAddress(GetModuleHandle(_T("kernel32.dll")), - // "Wow64RevertWow64FsRedirection"); - if (Wow64DisableWow64FsRedirection(&OldValue) == FALSE) { - MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRCANCELFSREDIRECT, - IDS_STR_INSTALL_FAILED, MB_ICONERROR | MB_OK); - return 1; - } - - if (is_arm64_machine()) { - WCHAR sysarm32[MAX_PATH]; - if (get_wow_arm32_system_dir(sysarm32, _countof(sysarm32)) > 0) { - // Install the ARM32 version if ARM32 WOW is supported (lower than - // Windows 11 24H2). - std::wstring srcPathARM32 = srcPath; - ireplace_last(srcPathARM32, ext, L"ARM" + ext); - - std::wstring destPathARM32 = std::wstring(sysarm32) + L"\\weasel" + ext; - if (!copy_file(srcPathARM32, destPathARM32)) { - MSG_NOT_SILENT_ID_CAP(silent, destPathARM32.c_str(), - IDS_STR_INSTALL_FAILED, MB_ICONERROR | MB_OK); - return 1; - } - retval += func(destPathARM32, true, true, true, hant, silent); - } - - // Then install the ARM64 (and x64) version. - // On ARM64 weasel.dll(ime) is an ARM64X redirection DLL (weaselARM64X). - // When loaded, it will be redirected to weaselARM64.dll(ime) on ARM64 - // processes, and weaselx64.dll(ime) on x64 processes. So we need a total - // of three files. - - std::wstring srcPathX64 = srcPath; - std::wstring destPathX64 = destPath; - ireplace_last(srcPathX64, ext, L"x64" + ext); - ireplace_last(destPathX64, ext, L"x64" + ext); - if (!copy_file(srcPathX64, destPathX64)) { - MSG_NOT_SILENT_ID_CAP(silent, destPathX64.c_str(), - IDS_STR_INSTALL_FAILED, MB_ICONERROR | MB_OK); - return 1; - } - - std::wstring srcPathARM64 = srcPath; - std::wstring destPathARM64 = destPath; - ireplace_last(srcPathARM64, ext, L"ARM64" + ext); - ireplace_last(destPathARM64, ext, L"ARM64" + ext); - if (!copy_file(srcPathARM64, destPathARM64)) { - MSG_NOT_SILENT_ID_CAP(silent, destPathARM64.c_str(), - IDS_STR_INSTALL_FAILED, MB_ICONERROR | MB_OK); - return 1; - } - - // Since weaselARM64X is just a redirector we don't have separate - // HANS and HANT variants. - srcPath = std::wstring(drive) + dir + L"weaselARM64X" + ext; - } else { - ireplace_last(srcPath, ext, L"x64" + ext); - } - - if (!copy_file(srcPath, destPath)) { - MSG_NOT_SILENT_ID_CAP(silent, destPath.c_str(), IDS_STR_INSTALL_FAILED, - MB_ICONERROR | MB_OK); - return 1; - } - retval += func(destPath, true, true, false, hant, silent); - if (Wow64RevertWow64FsRedirection(OldValue) == FALSE) { - MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRRECOVERFSREDIRECT, - IDS_STR_INSTALL_FAILED, MB_ICONERROR | MB_OK); - return 1; - } - } - return retval; -} - -int uninstall_ime_file(const std::wstring& ext, - bool silent, - ime_register_func func) { - int retval = 0; - WCHAR path[MAX_PATH]; - GetSystemDirectoryW(path, _countof(path)); - std::wstring imePath(path); - imePath += L"\\weasel" + ext; - retval += func(imePath, false, false, false, false, silent); - delete_file(imePath); - if (is_wow64()) { - retval += func(imePath, false, true, false, false, silent); - 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; - } - - if (is_arm64_machine()) { - WCHAR sysarm32[MAX_PATH]; - if (get_wow_arm32_system_dir(sysarm32, _countof(sysarm32)) > 0) { - std::wstring imePathARM32 = std::wstring(sysarm32) + L"\\weasel" + ext; - retval += func(imePathARM32, false, true, true, false, silent); - delete_file(imePathARM32); - } - - std::wstring imePathX64 = imePath; - ireplace_last(imePathX64, ext, L"x64" + ext); - delete_file(imePathX64); - - std::wstring imePathARM64 = imePath; - ireplace_last(imePathARM64, ext, L"ARM64" + ext); - delete_file(imePathARM64); - } - - delete_file(imePath); - if (Wow64RevertWow64FsRedirection(OldValue) == FALSE) { - MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_ERRRECOVERFSREDIRECT, - IDS_STR_UNINSTALL_FAILED, MB_ICONERROR | MB_OK); - return 1; - } - } - return retval; -} - -// 注册IME输入法 -int register_ime(const std::wstring& ime_path, - bool register_ime, - bool is_wow64, - bool is_wowarm, - bool hant, - bool silent) { - if (is_wow64) { - return 0; // only once - } - - const WCHAR KEYBOARD_LAYOUTS_KEY[] = - L"SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts"; - const WCHAR PRELOAD_KEY[] = L"Keyboard Layout\\Preload"; - - if (register_ime) { - HKL hKL = ImmInstallIME(ime_path.c_str(), get_weasel_ime_name().c_str()); - if (!hKL) { - // manually register ime - WCHAR hkl_str[16] = {0}; - HKEY hKey; - LSTATUS ret = RegOpenKey(HKEY_LOCAL_MACHINE, KEYBOARD_LAYOUTS_KEY, &hKey); - if (ret == ERROR_SUCCESS) { - for (DWORD k = 0xE0200000 + (hant ? 0x0404 : 0x0804); k <= 0xE0FF0804; - k += 0x10000) { - StringCchPrintfW(hkl_str, _countof(hkl_str), L"%08X", k); - HKEY hSubKey; - ret = RegOpenKey(hKey, hkl_str, &hSubKey); - if (ret == ERROR_SUCCESS) { - WCHAR imeFile[32] = {0}; - DWORD len = sizeof(imeFile); - DWORD type = 0; - ret = RegQueryValueEx(hSubKey, L"Ime File", NULL, &type, - (LPBYTE)imeFile, &len); - if (ret = ERROR_SUCCESS) { - if (_wcsicmp(imeFile, L"weasel.ime") == 0) { - hKL = (HKL)k; // already there - } - } - RegCloseKey(hSubKey); - } else { - // found a spare number to register - ret = RegCreateKey(hKey, hkl_str, &hSubKey); - if (ret == ERROR_SUCCESS) { - const WCHAR ime_file[] = L"weasel.ime"; - RegSetValueEx(hSubKey, L"Ime File", 0, REG_SZ, (LPBYTE)ime_file, - sizeof(ime_file)); - const WCHAR layout_file[] = L"kbdus.dll"; - RegSetValueEx(hSubKey, L"Layout File", 0, REG_SZ, - (LPBYTE)layout_file, sizeof(layout_file)); - const std::wstring layout_text = get_weasel_ime_name(); - RegSetValueEx(hSubKey, L"Layout Text", 0, REG_SZ, - (LPBYTE)layout_text.c_str(), - layout_text.size() * sizeof(wchar_t)); - RegCloseKey(hSubKey); - hKL = (HKL)k; - } - break; - } - } - RegCloseKey(hKey); - } - if (hKL) { - HKEY hPreloadKey; - ret = RegOpenKey(HKEY_CURRENT_USER, PRELOAD_KEY, &hPreloadKey); - if (ret == ERROR_SUCCESS) { - for (size_t i = 1; true; ++i) { - std::wstring number = std::to_wstring(i); - DWORD type = 0; - WCHAR value[32]; - DWORD len = sizeof(value); - ret = RegQueryValueEx(hPreloadKey, number.c_str(), 0, &type, - (LPBYTE)value, &len); - if (ret != ERROR_SUCCESS) { - RegSetValueEx(hPreloadKey, number.c_str(), 0, REG_SZ, - (const BYTE*)hkl_str, - (wcslen(hkl_str) + 1) * sizeof(WCHAR)); - break; - } - } - RegCloseKey(hPreloadKey); - } - } - } - if (!hKL) { - DWORD dwErr = GetLastError(); - WCHAR msg[100]; - CString str; - str.LoadStringW(IDS_STR_ERRREGIME); - StringCchPrintfW(msg, _countof(msg), str, hKL, dwErr); - MSG_NOT_SILENT_ID_CAP(silent, msg, IDS_STR_INSTALL_FAILED, - MB_ICONERROR | MB_OK); - return 1; - } - return 0; - } - - // unregister ime - - HKEY hKey; - LSTATUS ret = RegOpenKey(HKEY_LOCAL_MACHINE, KEYBOARD_LAYOUTS_KEY, &hKey); - if (ret != ERROR_SUCCESS) { - MSG_NOT_SILENT_ID_CAP(silent, KEYBOARD_LAYOUTS_KEY, - IDS_STR_UNINSTALL_FAILED, MB_ICONERROR | MB_OK); - return 1; - } - - for (int i = 0; true; ++i) { - WCHAR subKey[16]; - ret = RegEnumKey(hKey, i, subKey, _countof(subKey)); - if (ret != ERROR_SUCCESS) - break; - - // 中文键盘布局? - if (wcscmp(subKey + 4, L"0804") == 0 || wcscmp(subKey + 4, L"0404") == 0) { - HKEY hSubKey; - ret = RegOpenKey(hKey, subKey, &hSubKey); - if (ret != ERROR_SUCCESS) - continue; - - WCHAR imeFile[32]; - DWORD len = sizeof(imeFile); - DWORD type = 0; - ret = RegQueryValueEx(hSubKey, L"Ime File", NULL, &type, (LPBYTE)imeFile, - &len); - RegCloseKey(hSubKey); - if (ret != ERROR_SUCCESS) - continue; - - // 小狼毫? - if (_wcsicmp(imeFile, L"weasel.ime") == 0) { - DWORD value; - swscanf_s(subKey, L"%x", &value); - UnloadKeyboardLayout((HKL)value); - - RegDeleteKey(hKey, subKey); - - // 移除preload - HKEY hPreloadKey; - ret = RegOpenKey(HKEY_CURRENT_USER, PRELOAD_KEY, &hPreloadKey); - if (ret != ERROR_SUCCESS) - continue; - std::vector preloads; - std::wstring number; - for (size_t i = 1; true; ++i) { - number = std::to_wstring(i); - DWORD type = 0; - WCHAR value[32]; - DWORD len = sizeof(value); - ret = RegQueryValueEx(hPreloadKey, number.c_str(), 0, &type, - (LPBYTE)value, &len); - if (ret != ERROR_SUCCESS) { - if (i > preloads.size()) { - // 删除最大一号注册表值 - number = std::to_wstring(i - 1); - RegDeleteValue(hPreloadKey, number.c_str()); - } - break; - } - if (_wcsicmp(subKey, value) != 0) { - preloads.push_back(value); - } - } - // 重写preloads - for (size_t i = 0; i < preloads.size(); ++i) { - number = std::to_wstring(i + 1); - RegSetValueEx(hPreloadKey, number.c_str(), 0, REG_SZ, - (const BYTE*)preloads[i].c_str(), - (preloads[i].length() + 1) * sizeof(WCHAR)); - } - RegCloseKey(hPreloadKey); - } - } - } - - RegCloseKey(hKey); - return 0; -} - -void enable_profile(BOOL fEnable, bool hant) { - HRESULT hr; - ITfInputProcessorProfiles* pProfiles = NULL; - - hr = CoCreateInstance(CLSID_TF_InputProcessorProfiles, NULL, - CLSCTX_INPROC_SERVER, IID_ITfInputProcessorProfiles, - (LPVOID*)&pProfiles); - - if (SUCCEEDED(hr)) { - LANGID lang_id = hant ? 0x0404 : 0x0804; - if (fEnable) { - pProfiles->EnableLanguageProfile(c_clsidTextService, lang_id, - c_guidProfile, fEnable); - pProfiles->EnableLanguageProfileByDefault(c_clsidTextService, lang_id, - c_guidProfile, fEnable); - } else { - pProfiles->RemoveLanguageProfile(c_clsidTextService, lang_id, - c_guidProfile); - } - - pProfiles->Release(); - } -} - -// 注册TSF输入法 -int register_text_service(const std::wstring& tsf_path, - bool register_ime, - bool is_wow64, - bool is_wowarm32, - bool hant, - bool silent) { - using RegisterServerFunction = HRESULT(STDAPICALLTYPE*)(); - - if (!register_ime) - enable_profile(FALSE, hant); - - std::wstring params = L" \"" + tsf_path + L"\""; - if (!register_ime) { - params = L" /u " + params; // unregister - } - // if (silent) // always silent - { params = L" /s " + params; } - - if (hant) { - if (!SetEnvironmentVariable(L"TEXTSERVICE_PROFILE", L"hant")) { - // bad luck - } - } else { - if (!SetEnvironmentVariable(L"TEXTSERVICE_PROFILE", L"hans")) { - // bad luck - } - } - - std::wstring app = L"regsvr32.exe"; - if (is_wowarm32) { - WCHAR sysarm32[MAX_PATH]; - get_wow_arm32_system_dir(sysarm32, _countof(sysarm32)); - - app = std::wstring(sysarm32) + L"\\" + app; - } - - SHELLEXECUTEINFOW shExInfo = {0}; - shExInfo.cbSize = sizeof(shExInfo); - shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS; - shExInfo.hwnd = 0; - shExInfo.lpVerb = L"open"; // Operation to perform - shExInfo.lpFile = app.c_str(); // Application to start - shExInfo.lpParameters = params.c_str(); // Additional parameters - shExInfo.lpDirectory = 0; - shExInfo.nShow = SW_SHOW; - shExInfo.hInstApp = 0; - if (ShellExecuteExW(&shExInfo)) { - WaitForSingleObject(shExInfo.hProcess, INFINITE); - CloseHandle(shExInfo.hProcess); - } else { - WCHAR msg[100]; - CString str; - str.LoadStringW(IDS_STR_ERRREGTSF); - StringCchPrintfW(msg, _countof(msg), str, params.c_str()); - // StringCchPrintfW(msg, _countof(msg), L"註冊輸入法錯誤 regsvr32.exe %s", - // params.c_str()); if (!silent) MessageBoxW(NULL, msg, L"安装/卸載失败", - // MB_ICONERROR | MB_OK); - MSG_NOT_SILENT_ID_CAP(silent, msg, IDS_STR_INORUN_FAILED, - MB_ICONERROR | MB_OK); - return 1; - } - - if (register_ime) - enable_profile(TRUE, hant); - - return 0; -} - -int install(bool hant, bool silent, bool old_ime_support) { - std::wstring ime_src_path; - int retval = 0; - if (old_ime_support) { - retval += - install_ime_file(ime_src_path, L".ime", hant, silent, ®ister_ime); - } - retval += install_ime_file(ime_src_path, L".dll", hant, silent, - ®ister_text_service); - - // 写注册表 - 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(); - 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); - return 1; - } - - const std::wstring executable = L"WeaselServer.exe"; - 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; - } - - // InstallLayoutOrTip - // https://learn.microsoft.com/zh-cn/windows/win32/tsf/installlayoutortip - // example in ref page not right with "*PTF_ INSTALLLAYOUTORTIP" - // space inside should be removed - HMODULE hInputDLL = LoadLibrary(TEXT("input.dll")); - if (hInputDLL) { - PTF_INSTALLLAYOUTORTIP pfnInstallLayoutOrTip; - pfnInstallLayoutOrTip = - (PTF_INSTALLLAYOUTORTIP)GetProcAddress(hInputDLL, "InstallLayoutOrTip"); - if (pfnInstallLayoutOrTip) { - if (hant) - (*pfnInstallLayoutOrTip)(PSZTITLE_HANT, 0); - else - (*pfnInstallLayoutOrTip)(PSZTITLE_HANS, 0); - } - FreeLibrary(hInputDLL); - } - - // https://learn.microsoft.com/zh-cn/windows/win32/wer/collecting-user-mode-dumps - 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 - SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_WER_KEY, L"DumpType", 0, REG_DWORD, - true); - // CustomDumpFlags, MiniDumpNormal - SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_WER_KEY, L"CustomDumpFlags", 0, - REG_DWORD, true); - // maximium dump count 10 - SetRegKeyValue(HKEY_LOCAL_MACHINE, WEASEL_WER_KEY, L"DumpCount", 10, - REG_DWORD, true); - - if (retval) - return 1; - - MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_INSTALL_SUCCESS_INFO, - IDS_STR_INSTALL_SUCCESS_CAP, - MB_ICONINFORMATION | MB_OK); - return 0; -} - -int uninstall(bool silent) { - // 注销输入法 - int retval = 0; - - const WCHAR KEY[] = L"Software\\Rime\\Weasel"; - HKEY hKey; - LSTATUS ret = RegOpenKey(HKEY_CURRENT_USER, KEY, &hKey); - if (ret == ERROR_SUCCESS) { - DWORD type = 0; - DWORD data = 0; - DWORD len = sizeof(data); - ret = RegQueryValueEx(hKey, L"Hant", NULL, &type, (LPBYTE)&data, &len); - if (ret == ERROR_SUCCESS && type == REG_DWORD) { - HMODULE hInputDLL = LoadLibrary(TEXT("input.dll")); - if (hInputDLL) { - PTF_INSTALLLAYOUTORTIP pfnInstallLayoutOrTip; - pfnInstallLayoutOrTip = (PTF_INSTALLLAYOUTORTIP)GetProcAddress( - hInputDLL, "InstallLayoutOrTip"); - if (pfnInstallLayoutOrTip) { - if (data != 0) - (*pfnInstallLayoutOrTip)(PSZTITLE_HANT, ILOT_UNINSTALL); - else - (*pfnInstallLayoutOrTip)(PSZTITLE_HANS, ILOT_UNINSTALL); - } - FreeLibrary(hInputDLL); - } - } - RegCloseKey(hKey); - } - - uninstall_ime_file(L".ime", silent, ®ister_ime); - retval += uninstall_ime_file(L".dll", silent, ®ister_text_service); - - // 清除注册信息 - RegDeleteKey(HKEY_LOCAL_MACHINE, WEASEL_REG_KEY); - RegDeleteKey(HKEY_LOCAL_MACHINE, RIME_REG_KEY); - - // 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; - - MSG_NOT_SILENT_BY_IDS(silent, IDS_STR_UNINSTALL_SUCCESS_INFO, - IDS_STR_UNINSTALL_SUCCESS_CAP, - MB_ICONINFORMATION | MB_OK); - return 0; -} - -bool has_installed() { - WCHAR path[MAX_PATH]; - GetSystemDirectory(path, _countof(path)); - std::wstring sysPath(path); - DWORD attr = GetFileAttributesW((sysPath + L"\\weasel.dll").c_str()); - return (attr != INVALID_FILE_ATTRIBUTES && - !(attr & FILE_ATTRIBUTE_DIRECTORY)); -} diff --git a/WeaselSetup/resource.h b/WeaselSetup/resource.h deleted file mode 100644 index 3315f0f94..000000000 --- a/WeaselSetup/resource.h +++ /dev/null @@ -1,48 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by WeaselSetup.rc -// -#define IDI_WEASELSETUP 107 -#define IDR_WEASELSETUP 107 -#define IDR_MAINFRAME 128 -#define IDS_STRING_INSTALL 129 -#define IDS_STRING_MODIFY 130 -#define IDS_STR_INSTALL_FAILED 131 -#define IDS_STR_INSTALL_SUCCESS_CAP 132 -#define IDS_STR_UNINSTALL_SUCCESS_CAP 133 -#define IDS_STR_UNINSTALL_FAILED 134 -#define IDS_STR_ERRCANCELFSREDIRECT 135 -#define IDS_STR_ERRRECOVERFSREDIRECT 136 -#define IDS_STR_ERRREGIME 137 -#define IDS_STR_ERRREGTSF 138 -#define IDS_STR_ERRREGIMEWRITESVREXE 139 -#define IDS_STR_INORUN_FAILED 140 -#define IDS_STR_ERRWRITEWEASELROOT 141 -#define IDS_STR_INSTALL_SUCCESS_INFO 142 -#define IDS_STR_UNINSTALL_SUCCESS_INFO 143 -#define IDS_STR_ERR_WRITE_USER_DIR 144 -#define IDS_STR_ERR_WRITE_HANT 145 -#define IDS_STR_MODIFY_SUCCESS_INFO 146 -#define IDS_STR_MODIFY_SUCCESS_CAP 147 -#define IDD_INSTALL_OPTIONS 201 -#define IDD_DIALOG1 203 -#define IDC_RADIO_CN 1000 -#define IDC_RADIO_TW 1001 -#define IDC_RADIO_DEFAULT_DIR 1002 -#define IDC_RADIO_CUSTOM_DIR 1003 -#define IDC_EDIT_DIR 1004 -#define IDC_REMOVE 1005 -#define IDC_CHECK1 1006 -#define IDC_CHECK_INSTIME 1006 -#define IDC_BUTTON_CUSTOM_DIR 1007 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 205 -#define _APS_NEXT_COMMAND_VALUE 32775 -#define _APS_NEXT_CONTROL_VALUE 1008 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif diff --git a/WeaselSetup/stdafx.cpp b/WeaselSetup/stdafx.cpp deleted file mode 100644 index af034a721..000000000 --- a/WeaselSetup/stdafx.cpp +++ /dev/null @@ -1,5 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// WeaselSetup.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" diff --git a/WeaselSetup/stdafx.h b/WeaselSetup/stdafx.h deleted file mode 100644 index 1fc659710..000000000 --- a/WeaselSetup/stdafx.h +++ /dev/null @@ -1,34 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently -// - -#pragma once - -// Change these values to use different versions -#define WINVER 0x0603 -#define _WIN32_WINNT 0x0603 -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers - -#include -#include - -extern CAppModule _Module; - -#include - -#include -#include -#include - -#include -#include -#include - -#if defined _M_IX86 - #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='x86' publicKeyToken='6595b64144ccf1df' language='*'\"") -#elif defined _M_X64 - #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='amd64' publicKeyToken='6595b64144ccf1df' language='*'\"") -#else - #pragma comment(linker, "/manifestdependency:\"type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") -#endif diff --git a/WeaselSetup/xmake.lua b/WeaselSetup/xmake.lua deleted file mode 100644 index 865392e46..000000000 --- a/WeaselSetup/xmake.lua +++ /dev/null @@ -1,33 +0,0 @@ -target("WeaselSetup") - set_kind("binary") - add_files("./*.cpp") - add_rules("add_rcfiles", "use_weaselconstants", "subwin") - add_links("imm32", "kernel32") - - set_policy("windows.manifest.uac", "invoker") - add_files("$(projectdir)/PerMonitorHighDPIAware.manifest") - add_ldflags("/DEBUG /OPT:REF /OPT:ICF /LARGEADDRESSAWARE /ERRORREPORT:QUEUE") - - before_build(function(target) - local target_dir = path.join(target:targetdir(), target:name()) - if not os.exists(target_dir) then - os.mkdir(target_dir) - end - target:set("targetdir", target_dir) - local level = target:policy("windows.manifest.uac") - if level then - local level_maps = { - invoker = "asInvoker", - admin = "requireAdministrator", - highest = "highestAvailable" - } - assert(level_maps[level], "unknown uac level %s, please set invoker, admin or highest", level) - local ui = target:policy("windows.manifest.uac.ui") or false - target:add("ldflags", "/manifest:embed", {("/manifestuac:level='%s' uiAccess='%s'"):format(level_maps[level], ui)}, {force = true, expand = false}) - end - end) - - after_build(function(target) - os.cp(path.join(target:targetdir(), "WeaselSetup.exe"), "$(projectdir)/output") - os.cp(path.join(target:targetdir(), "WeaselSetup.pdb"), "$(projectdir)/output") - end) diff --git a/weasel.sln b/weasel.sln index df8e78a35..f94ebbb2a 100644 --- a/weasel.sln +++ b/weasel.sln @@ -41,8 +41,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RimeWithWeasel", "RimeWithW EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WeaselDeployer", "WeaselDeployer\WeaselDeployer.vcxproj", "{F53F3E9C-CC4D-4D1D-9C2E-719FE60A7E6B}" EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "WeaselSetup", "WeaselSetup\WeaselSetup.vcxproj", "{39F6E3F5-8F0B-4023-BC40-A66AE6C37095}" -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Weasel.Setup", "Weasel.Setup\Weasel.Setup.csproj", "{2D028423-929D-4555-A61E-245BD9EC7383}" EndProject Global @@ -231,20 +229,6 @@ Global {F53F3E9C-CC4D-4D1D-9C2E-719FE60A7E6B}.Release|Win32.Build.0 = Release|Win32 {F53F3E9C-CC4D-4D1D-9C2E-719FE60A7E6B}.Release|x64.ActiveCfg = Release|x64 {F53F3E9C-CC4D-4D1D-9C2E-719FE60A7E6B}.Release|x64.Build.0 = Release|x64 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Debug|Any CPU.ActiveCfg = Debug|Win32 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Debug|Any CPU.Build.0 = Debug|Win32 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Debug|ARM.ActiveCfg = Debug|Win32 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Debug|ARM64.ActiveCfg = Debug|Win32 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Debug|Win32.ActiveCfg = Debug|Win32 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Debug|Win32.Build.0 = Debug|Win32 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Debug|x64.ActiveCfg = Debug|Win32 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Release|Any CPU.ActiveCfg = Release|Win32 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Release|Any CPU.Build.0 = Release|Win32 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Release|ARM.ActiveCfg = Release|Win32 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Release|ARM64.ActiveCfg = Release|Win32 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Release|Win32.ActiveCfg = Release|Win32 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Release|Win32.Build.0 = Release|Win32 - {39F6E3F5-8F0B-4023-BC40-A66AE6C37095}.Release|x64.ActiveCfg = Release|Win32 {2D028423-929D-4555-A61E-245BD9EC7383}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2D028423-929D-4555-A61E-245BD9EC7383}.Debug|Any CPU.Build.0 = Debug|Any CPU {2D028423-929D-4555-A61E-245BD9EC7383}.Debug|ARM.ActiveCfg = Debug|Any CPU