Fixed single instance checks to run much earlier, so we don't initialize

anything (library, output devices, indexer, etc) if we haveh to die
immediately.
This commit is contained in:
casey langen 2017-06-12 10:31:06 -07:00
parent 8344255b18
commit 2852648c5b
5 changed files with 43 additions and 21 deletions

View File

@ -87,13 +87,14 @@ using namespace cursespp;
int _main(int argc, wchar_t* argv[]);
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow) {
_main(0, 0);
return App::Running("musikbox") ? 0 : _main(0, 0);
}
int _main(int argc, wchar_t* argv[]) {
#else
int main(int argc, char* argv[]) {
#endif
srand((unsigned int) time(0));
/* the following allows boost::filesystem to use utf8 on Windows */

View File

@ -75,6 +75,7 @@ App::App(const std::string& title) {
#ifdef WIN32
this->iconId = 0;
this->appTitle = title;
win32::ConfigureDpiAwareness();
#else
setlocale(LC_ALL, "");
@ -187,15 +188,27 @@ void App::OnResized() {
}
}
#ifdef WIN32
bool App::Running(const std::string& uniqueId) {
return App::Running(uniqueId, uniqueId);
}
bool App::Running(const std::string& uniqueId, const std::string& title) {
if (uniqueId.size()) {
win32::EnableSingleInstance(uniqueId);
if (win32::AlreadyRunning()) {
win32::ShowOtherInstance(title);
return true;
}
}
return false;
}
#endif
void App::Run(ILayoutPtr layout) {
#ifdef WIN32
if (this->uniqueId.size()) {
win32::EnableSingleInstance(uniqueId);
if (win32::AlreadyRunning()) {
win32::ShowOtherInstance();
return;
}
if (App::Running(this->uniqueId, this->appTitle)) {
return;
}
#endif

View File

@ -61,6 +61,8 @@ namespace cursespp {
void Restore();
#ifdef WIN32
static bool Running(const std::string& uniqueId, const std::string& title);
static bool Running(const std::string& title);
void SetIcon(int resourceId);
void SetSingleInstanceId(const std::string& uniqueId);
#endif
@ -111,7 +113,7 @@ namespace cursespp {
#ifdef WIN32
int iconId;
std::string uniqueId;
std::string uniqueId, appTitle;
#endif
};
}

View File

@ -52,6 +52,8 @@ static std::unique_ptr<NOTIFYICONDATA> trayIcon;
static bool minimizeToTray = false, minimizedToTray = false;
static std::string appTitle;
static HICON icon16 = nullptr, icon32 = nullptr;
static std::string runingMutexName;
static HANDLE runningMutex;
static DWORD runningMutexLastError = 0;
@ -78,7 +80,7 @@ static HWND findThisProcessMainWindow() {
return nullptr;
}
static HWND findOtherProcessMainWindow() {
static HWND findOtherProcessMainWindow(const std::string& title) {
static TCHAR buffer[256];
DWORD dwProcID = GetCurrentProcessId();
@ -91,7 +93,7 @@ static HWND findOtherProcessMainWindow() {
GetClassName(hWnd, buffer, sizeof(buffer));
if (className == std::basic_string<TCHAR>(buffer)) {
::GetWindowText(hWnd, buffer, sizeof(buffer));
if (appTitle == u16to8(buffer)) { /* title must match*/
if (title == u16to8(buffer)) { /* title must match*/
return hWnd;
}
}
@ -231,11 +233,11 @@ namespace cursespp {
}
bool AlreadyRunning() {
return !IsDebuggerPresent() && (runningMutexLastError == ERROR_ALREADY_EXISTS);
return /*!IsDebuggerPresent() &&*/ (runningMutexLastError == ERROR_ALREADY_EXISTS);
}
void ShowOtherInstance() {
HWND otherHwnd = findOtherProcessMainWindow();
void ShowOtherInstance(const std::string& title) {
HWND otherHwnd = findOtherProcessMainWindow(title);
if (otherHwnd) {
SendMessage(otherHwnd, WM_SHOW_OTHER_INSTANCE, 0, 0);
::SetForegroundWindow(otherHwnd);
@ -243,13 +245,17 @@ namespace cursespp {
}
void EnableSingleInstance(const std::string& uniqueId) {
if (uniqueId.size() && !runningMutex) {
std::string mutexName = "cursespp::" + uniqueId;
runningMutex = CreateMutexA(nullptr, false, mutexName.c_str());
runningMutexLastError = GetLastError();
}
else {
if (!uniqueId.size()) {
resetMutex();
return;
}
std::string mutexName = "cursespp::" + uniqueId;
if (mutexName != runingMutexName) {
resetMutex();
runingMutexName = mutexName;
runningMutex = CreateMutexA(nullptr, false, runingMutexName.c_str());
runningMutexLastError = GetLastError();
}
}

View File

@ -50,7 +50,7 @@ namespace cursespp {
void SetMinimizeToTray(bool enabled);
void EnableSingleInstance(const std::string& uniqueId);
bool AlreadyRunning();
void ShowOtherInstance();
void ShowOtherInstance(const std::string& title);
void ConfigureDpiAwareness();
}
}