Files
hrynco-kswitcher/src/main.cpp
T

91 lines
2.9 KiB
C++

#include "app.h"
#include <shellapi.h>
#include <shlobj.h>
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"--capture")
cmd = ks::Screenshot;
else 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;
}