diff --git a/README.md b/README.md index 7518c82..3c7559d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,17 @@ + +# Static compilation +```powershell +# compile release +& 'C:\Program Files\Microsoft Visual Studio\2022\Community\MSBuild\Current\Bin\MSBuild.exe' /m:8 /property:Configuration=Release .\singleinstance.sln + +# check dll depends +&'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.43.34808\bin\Hostx64\x64\dumpbin.exe' /dependents .\Release\singleinstance.exe +``` + # context-menu-launcher Select multiple files from Windows Explorer menu and launch just one instance of process -[Download executable](https://github.com/zenden2k/context-menu-launcher/releases/tag/1.0) +[Download executable](https://github.com/owenstake/context-menu-launcher/releases/download/latest/singleinstance.exe) ## How to pass multiple files to shell context menu command (Windows Explorer) diff --git a/singleinstance/singleinstance.cpp b/singleinstance/singleinstance.cpp index 1c40a39..97a494e 100644 --- a/singleinstance/singleinstance.cpp +++ b/singleinstance/singleinstance.cpp @@ -18,32 +18,34 @@ Windows Registry Editor Version 5.00 */ #include +#include #include #include +#include class CLimitSingleInstance { -protected: - DWORD m_dwLastError; - HANDLE m_hMutex; + protected: + DWORD m_dwLastError; + HANDLE m_hMutex; -public: - CLimitSingleInstance(TCHAR *strMutexName) - { - m_hMutex = CreateMutex(NULL, FALSE, strMutexName); //do early - m_dwLastError = GetLastError(); //save for use later... - } - - ~CLimitSingleInstance(){ - if (m_hMutex) //Do not forget to close handles. + public: + CLimitSingleInstance(TCHAR *strMutexName) { - CloseHandle(m_hMutex); //Do as late as possible. - m_hMutex = NULL; //Good habit to be in. + m_hMutex = CreateMutex(NULL, FALSE, strMutexName); //do early + m_dwLastError = GetLastError(); //save for use later... } - } - BOOL IsAnotherInstanceRunning(){ - return (ERROR_ALREADY_EXISTS == m_dwLastError); - } + ~CLimitSingleInstance(){ + if (m_hMutex) //Do not forget to close handles. + { + CloseHandle(m_hMutex); //Do as late as possible. + m_hMutex = NULL; //Good habit to be in. + } + } + + BOOL IsAnotherInstanceRunning(){ + return (ERROR_ALREADY_EXISTS == m_dwLastError); + } }; int timeout = 400; // ms @@ -158,13 +160,19 @@ BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) { return TRUE; } -void ArgvQuote(const std::wstring& Argument, std::wstring& CommandLine, bool Force){ +void ArgvQuote(const std::wstring& Argument, std::wstring& CommandLine, bool Force, bool singlequote){ + wchar_t mark; + if (singlequote) { + mark = L'\''; + } else { + mark = L'"'; + } if (Force == false && Argument.empty() == false && Argument.find_first_of(L" \t\n\v\"") == Argument.npos) { CommandLine.append(Argument); } else { - CommandLine.push_back(L'"'); + CommandLine.push_back(mark); for (auto It = Argument.begin();; ++It) { unsigned NumberBackslashes = 0; @@ -196,7 +204,7 @@ void ArgvQuote(const std::wstring& Argument, std::wstring& CommandLine, bool For } } - CommandLine.push_back(L'"'); + CommandLine.push_back(mark); } CommandLine.push_back(L' '); } @@ -205,18 +213,22 @@ void LaunchApp() { std::wstring cmdLine; for (int i = 3; i < argCount; i++) { - if (!lstrcmp(szArgList[i], _T("$files"))) { + std::wstring argStr = szArgList[i]; + std::size_t found = argStr.find(L"$files"); + if (found!=std::string::npos) { + std::wstring tmpstr; for (const auto& file : files) { - ArgvQuote(file, cmdLine, true); + ArgvQuote(file, tmpstr, true, true); } - } else if (!lstrcmp(szArgList[i], _T("--si-timeout"))) { + argStr = std::regex_replace(argStr, std::wregex(L"\\$files"), tmpstr); + cmdLine.append(argStr); + } else if (argStr == L"--si-timeout") { i++; // skip - } - else { - ArgvQuote(szArgList[i], cmdLine, true); + } else { + ArgvQuote(argStr, cmdLine, true, false); } } - //MessageBox(0, cmdLine.c_str(), szArgList[2], 0); + // MessageBox(0, cmdLine.c_str(), szArgList[2], 0); HINSTANCE hinst = ShellExecute(0, _T("open"), szArgList[2], cmdLine.c_str(), 0, SW_SHOWNORMAL); if (reinterpret_cast(hinst) <= 32) { TCHAR buffer[256]; @@ -237,6 +249,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) SetTimer(hWnd, TIMER_ID, timeout, 0); break; case WM_COPYDATA: + SetTimer(hWnd, TIMER_ID, timeout, 0); pcds = reinterpret_cast(lParam); if (pcds->dwData == 1) { LPCTSTR lpszString = reinterpret_cast(pcds->lpData); @@ -255,4 +268,4 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) return DefWindowProc(hWnd, message, wParam, lParam); } return 0; -} \ No newline at end of file +} diff --git a/singleinstance/singleinstance.vcxproj b/singleinstance/singleinstance.vcxproj index c93aebd..6b3a7f2 100644 --- a/singleinstance/singleinstance.vcxproj +++ b/singleinstance/singleinstance.vcxproj @@ -14,18 +14,19 @@ {95C5CED1-7955-43FC-9EA3-E20D2CE1DEB1} Win32Proj singleinstance + 10.0 Application true - v120 + v143 Unicode Application false - v120_xp + v143 true Unicode