#include "app.h" #include #include int WINAPI wWinMain(HINSTANCE instance, HINSTANCE, PWSTR, int) { CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED); int argc{}; auto argv = CommandLineToArgvW(GetCommandLineW(), &argc); std::wstring arg = argc > 1 ? argv[1] : L""; if (arg.starts_with(L"--configure-autostart=")) { int result = 1; try { if (argc != 3 || ks::currentUserSid() != argv[2] || !IsUserAnAdmin()) throw std::runtime_error("Administrator approval for the same Windows account is required"); if (arg != L"--configure-autostart=0" && arg != L"--configure-autostart=1" && arg != L"--configure-autostart=2") throw std::runtime_error("Invalid autostart mode"); ks::configureAutostart(arg.back() - L'0'); result = 0; } catch (const std::exception &e) { MessageBoxW(nullptr, ks::wide(e.what()).c_str(), L"KSwitcher autostart", MB_OK | MB_ICONERROR); } LocalFree(argv); CoUninitialize(); return result; } HANDLE mutex = CreateMutexW(nullptr, TRUE, L"Local\\KSwitcher.Native.Singleton"); bool existing = GetLastError() == ERROR_ALREADY_EXISTS; int cmd = ks::ShowHistory; if (arg == L"--convert") cmd = ks::Toggle; else if (arg == L"--case") cmd = ks::Case; else if (arg == L"--transliterate") cmd = ks::Translit; else if (arg == L"--settings") cmd = 20; else if (arg == L"--snippets") cmd = 21; else if (arg == L"--exit") cmd = 99; LocalFree(argv); if (existing) { HWND window = FindWindowW(L"KSwitcher.Main", L"KSwitcher"); if (window) { COPYDATASTRUCT data{1, sizeof(cmd), &cmd}; DWORD_PTR result{}; SendMessageTimeoutW(window, WM_COPYDATA, 0, (LPARAM)&data, SMTO_ABORTIFHUNG, 1000, &result); } CloseHandle(mutex); CoUninitialize(); return 0; } if (arg == L"--exit") { CloseHandle(mutex); CoUninitialize(); return 0; } int result = 0; try { ks::App app(instance, arg == L"--smoke-test"); if (arg.starts_with(L"--update-ready-event=")) app.updateStartupEvent = arg.substr(std::wstring(L"--update-ready-event=").size()); else if (!arg.empty() && arg != L"--smoke-test") app.startCommand = cmd; result = app.execute(); } catch (const std::exception &e) { MessageBoxW(nullptr, ks::wide(e.what()).c_str(), L"KSwitcher could not start", MB_OK | MB_ICONERROR); result = 1; } if (mutex) { ReleaseMutex(mutex); CloseHandle(mutex); } CoUninitialize(); return result; }