Index: src/ch/MainWnd.cpp =================================================================== diff -u -r3d1951f52696fe21e01618e1bbfb9e14745a3827 -r3127f6bb39be81d3b451ffbc3d0bad7f85d4a89f --- src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision 3d1951f52696fe21e01618e1bbfb9e14745a3827) +++ src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision 3127f6bb39be81d3b451ffbc3d0bad7f85d4a89f) @@ -187,55 +187,8 @@ // import tasks specified at command line (before loading current tasks) const TCommandLineParser& cmdLine = GetApp().GetCommandLine(); - if(cmdLine.HasTaskDefinitionPath()) - { - std::vector vTaskPaths; - cmdLine.GetTaskDefinitionPaths(vTaskPaths); + ProcessCommandLine(cmdLine); - const size_t stBufferSize = 4096; - boost::shared_array szBuffer(new wchar_t[stBufferSize]); - - BOOST_FOREACH(const CString& strPath, vTaskPaths) - { - bool bImported = false; - - try - { - CTaskPtr spTask = m_tasks.ImportTask(strPath); - if(spTask) - spTask->Store(); - bImported = true; - } - catch(icpf::exception& e) - { - bImported = false; - e.get_info(szBuffer.get(), stBufferSize); - } - catch(...) - { - bImported = false; - szBuffer.get()[0] = _T('\0'); - } - - if(!bImported) - { - ictranslate::CFormat fmt; - fmt.SetFormat(_T("Error encountered while importing task from path '%path'. Error: %err.")); - fmt.SetParam(_T("%path"), strPath); - fmt.SetParam(_T("%error"), szBuffer.get()); - - LOG_ERROR(fmt); - - fmt.SetFormat(GetResManager().LoadString(IDS_TASK_IMPORT_FAILED)); - fmt.SetParam(_T("%path"), strPath); - AfxMessageBox(fmt, MB_OK | MB_ICONERROR); - } - } - } - - // resume tasks - m_tasks.TasksRetryProcessing(); - // start clipboard monitoring LOG_INFO(_T("Starting clipboard monitor...")); CClipboardMonitor::StartMonitor(&m_tasks); @@ -517,12 +470,81 @@ // add to task list and start processing spTask->BeginProcessing(); + + break; } + case eCDType_CommandLineArguments: + { + // load task from buffer + wchar_t* pszBuffer = static_cast(pCopyDataStruct->lpData); + unsigned long ulLen = pCopyDataStruct->cbData / sizeof(wchar_t); + + // check if the string ends with '\0', so we can safely use it without length checks + if(!pszBuffer || ulLen == 0 || pszBuffer[ulLen - 1] != L'\0') + return FALSE; + + TCommandLineParser cmdLineParser; + cmdLineParser.ParseCommandLine(pszBuffer); + + ProcessCommandLine(cmdLineParser); + return TRUE; + } } return CWnd::OnCopyData(pWnd, pCopyDataStruct); } +void CMainWnd::ProcessCommandLine(const TCommandLineParser& rCommandLine) +{ + if(rCommandLine.HasTaskDefinitionPath()) + { + std::vector vTaskPaths; + rCommandLine.GetTaskDefinitionPaths(vTaskPaths); + + const size_t stBufferSize = 4096; + boost::shared_array szBuffer(new wchar_t[stBufferSize]); + + BOOST_FOREACH(const CString& strPath, vTaskPaths) + { + bool bImported = false; + + try + { + CTaskPtr spTask = m_tasks.ImportTask(strPath); + if(spTask) + spTask->Store(); + bImported = true; + } + catch(icpf::exception& e) + { + bImported = false; + e.get_info(szBuffer.get(), stBufferSize); + } + catch(...) + { + bImported = false; + szBuffer.get()[0] = _T('\0'); + } + + if(!bImported) + { + ictranslate::CFormat fmt; + fmt.SetFormat(_T("Error encountered while importing task from path '%path'. Error: %err.")); + fmt.SetParam(_T("%path"), strPath); + fmt.SetParam(_T("%error"), szBuffer.get()); + + LOG_ERROR(fmt); + + fmt.SetFormat(GetResManager().LoadString(IDS_TASK_IMPORT_FAILED)); + fmt.SetParam(_T("%path"), strPath); + AfxMessageBox(fmt, MB_OK | MB_ICONERROR); + } + } + + m_tasks.TasksRetryProcessing(); + } +} + void CMainWnd::OnShowMiniView() { m_pdlgMiniView=new CMiniViewDlg(&m_tasks, &CStatusDlg::m_bLock, this); // self-deleting Index: src/ch/MainWnd.h =================================================================== diff -u -rf703b71b8c856e2538283555e9fdbc84918677c3 -r3127f6bb39be81d3b451ffbc3d0bad7f85d4a89f --- src/ch/MainWnd.h (.../MainWnd.h) (revision f703b71b8c856e2538283555e9fdbc84918677c3) +++ src/ch/MainWnd.h (.../MainWnd.h) (revision 3127f6bb39be81d3b451ffbc3d0bad7f85d4a89f) @@ -68,6 +68,9 @@ int ShowTrayIcon(); void ShowStatusWindow(const CTaskPtr& spSelect = CTaskPtr()); void PrepareToExit(); + + void ProcessCommandLine(const TCommandLineParser& rCommandLine); + //{{AFX_MSG(CMainWnd) afx_msg void OnPopupShowStatus(); afx_msg void OnPopupShowOptions(); Index: src/ch/ch.cpp =================================================================== diff -u -r8dd3566d66a35a662872eaaa45eef5049e71c3dc -r3127f6bb39be81d3b451ffbc3d0bad7f85d4a89f --- src/ch/ch.cpp (.../ch.cpp) (revision 8dd3566d66a35a662872eaaa45eef5049e71c3dc) +++ src/ch/ch.cpp (.../ch.cpp) (revision 3127f6bb39be81d3b451ffbc3d0bad7f85d4a89f) @@ -302,9 +302,40 @@ LOG_INFO(_T("Checking for other running instances of Copy Handler")); if(!IsFirstInstance()) { - LOG_WARNING(_T("Other instance of Copy Handler is already running. Exiting.")); - MsgBox(IDS_ONECOPY_STRING); - return FALSE; + // if there is a command line specified, send it to the existing instance + if(m_cmdLineParser.HasCommandLineParams()) + { + HWND hWnd = ::FindWindow(_T("Copy Handler Wnd Class"), _T("Copy handler")); + if(hWnd == NULL) + { + // cannot pass command line to running ch + LOG_ERROR(_T("Cannot determine running CH's window. Cannot pass command line there.")); + MsgBox(IDS_COMMAND_LINE_FAILED_STRING, MB_OK | MB_ICONERROR); + return FALSE; + } + + CString strCmdLine = ::GetCommandLine(); + + COPYDATASTRUCT cds; + cds.dwData = eCDType_CommandLineArguments; + cds.cbData = (DWORD)(strCmdLine.GetLength() + 1) * sizeof(wchar_t); + cds.lpData = (void*)(PCTSTR)strCmdLine; + + // send a message to ch + if(::SendMessage(hWnd, WM_COPYDATA, NULL, reinterpret_cast(&cds)) == 0) + { + LOG_ERROR(_T("Command line was not processed properly at the running CH's instance.")); + MsgBox(IDS_COMMAND_LINE_FAILED_STRING, MB_OK | MB_ICONERROR); + } + + return FALSE; + } + else + { + LOG_WARNING(_T("Other instance of Copy Handler is already running. Exiting.")); + MsgBox(IDS_ONECOPY_STRING, MB_OK | MB_ICONWARNING); + return FALSE; + } } // ================================= Common controls ======================================== Index: src/ch/ch.rc =================================================================== diff -u -r8dd3566d66a35a662872eaaa45eef5049e71c3dc -r3127f6bb39be81d3b451ffbc3d0bad7f85d4a89f --- src/ch/ch.rc (.../ch.rc) (revision 8dd3566d66a35a662872eaaa45eef5049e71c3dc) +++ src/ch/ch.rc (.../ch.rc) (revision 3127f6bb39be81d3b451ffbc3d0bad7f85d4a89f) @@ -642,6 +642,8 @@ IDS_UNREGISTERERR_STRING "Encountered an error while trying to disable integration with system.\nError #%errno (%errdesc)." IDS_CRASH_STRING "Copy Handler encountered an internal problem and will be closed.\n\nIf you want to help correct this problem in the future releases of program you can send the crash information to the author of this program." + IDS_COMMAND_LINE_FAILED_STRING + "Cannot process command line arguments passed to Copy Handler." END STRINGTABLE Index: src/ch/resource.h =================================================================== diff -u -r8dd3566d66a35a662872eaaa45eef5049e71c3dc -r3127f6bb39be81d3b451ffbc3d0bad7f85d4a89f --- src/ch/resource.h (.../resource.h) (revision 8dd3566d66a35a662872eaaa45eef5049e71c3dc) +++ src/ch/resource.h (.../resource.h) (revision 3127f6bb39be81d3b451ffbc3d0bad7f85d4a89f) @@ -326,6 +326,7 @@ #define IDS_UNREGISTEROK_STRING 6003 #define IDS_UNREGISTERERR_STRING 6004 #define IDS_CRASH_STRING 6006 +#define IDS_COMMAND_LINE_FAILED_STRING 6007 #define IDS_PROGRAM_STRING 8000 #define IDS_CLIPBOARDMONITORING_STRING 8001 #define IDS_CLIPBOARDINTERVAL_STRING 8002