Index: src/ch/MainWnd.cpp =================================================================== diff -u -rb684bec49aaaea4b89ab2e599497f4085d8698a3 -r3cd8d4a64a63e4fb32d7dc96e46789c713698435 --- src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) +++ src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision 3cd8d4a64a63e4fb32d7dc96e46789c713698435) @@ -24,7 +24,6 @@ #include "FolderDialog.h" #include "CustomCopyDlg.h" #include "AboutDlg.h" -#include "register.h" #include "ShutdownDlg.h" #include "..\common\ipcstructs.h" #include "UpdateChecker.h" @@ -403,9 +402,6 @@ BOOL CMainWnd::OnCopyData(CWnd* pWnd, COPYDATASTRUCT* pCopyDataStruct) { - if(!GetApp().IsShellExtEnabled()) - return FALSE; - // copying or moving ? bool bMove=false; switch(pCopyDataStruct->dwData & CSharedConfigStruct::OPERATION_MASK) @@ -830,65 +826,12 @@ void CMainWnd::OnPopupRegisterdll() { - CString strPath; - CCopyHandlerApp& rApp = GetApp(); - if(rApp) - { - strPath = rApp.GetProgramPath(); - strPath += _T("\\"); - } - -#ifdef _WIN64 - strPath += _T("chext64.dll"); -#else - strPath += _T("chext.dll"); -#endif - HRESULT hResult = RegisterShellExtDll(strPath, true); - if(FAILED(hResult)) - { - TCHAR szStr[256]; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hResult, 0, szStr, 256, NULL); - while (szStr[_tcslen(szStr)-1] == _T('\n') || szStr[_tcslen(szStr)-1] == _T('\r') || szStr[_tcslen(szStr)-1] == _T('.')) - szStr[_tcslen(szStr)-1]=_T('\0'); - - ictranslate::CFormat fmt(GetResManager().LoadString(IDS_REGISTERERR_STRING)); - fmt.SetParam(_T("%errno"), (ulong_t)hResult); - fmt.SetParam(_T("%errdesc"), szStr); - AfxMessageBox(fmt, MB_ICONERROR | MB_OK); - } - else if(hResult == S_OK) - MsgBox(IDS_REGISTEROK_STRING, MB_ICONINFORMATION | MB_OK); + GetApp().RegisterShellExtension(); } void CMainWnd::OnPopupUnregisterdll() { - CString strPath; - CCopyHandlerApp& rApp = GetApp(); - strPath = rApp.GetProgramPath(); - strPath += _T("\\"); - -#ifdef _WIN64 - strPath += _T("chext64.dll"); -#else - strPath += _T("chext.dll"); -#endif - - HRESULT hResult = RegisterShellExtDll(strPath, false); - if(FAILED(hResult)) - { - TCHAR szStr[256]; - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hResult, 0, szStr, 256, NULL); - while (szStr[_tcslen(szStr)-1] == _T('\n') || szStr[_tcslen(szStr)-1] == _T('\r') || szStr[_tcslen(szStr)-1] == _T('.')) - szStr[_tcslen(szStr)-1]=_T('\0'); - - ictranslate::CFormat fmt(GetResManager().LoadString(IDS_UNREGISTERERR_STRING)); - fmt.SetParam(_T("%errno"), (ulong_t)hResult); - fmt.SetParam(_T("%errdesc"), szStr); - - AfxMessageBox(fmt, MB_ICONERROR | MB_OK); - } - else if(hResult == S_OK) - MsgBox(IDS_UNREGISTEROK_STRING, MB_ICONINFORMATION | MB_OK); + GetApp().UnregisterShellExtension(); } void CMainWnd::PrepareToExit() Index: src/ch/TShellExtensionClient.cpp =================================================================== diff -u --- src/ch/TShellExtensionClient.cpp (revision 0) +++ src/ch/TShellExtensionClient.cpp (revision 3cd8d4a64a63e4fb32d7dc96e46789c713698435) @@ -0,0 +1,215 @@ +/*************************************************************************** +* Copyright (C) 2001-2008 by J�zef Starosczyk * +* ixen@copyhandler.com * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU Library General Public License * +* (version 2) as published by the Free Software Foundation; * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public * +* License along with this program; if not, write to the * +* Free Software Foundation, Inc., * +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +***************************************************************************/ +#include "stdafx.h" +#include "TShellExtensionClient.h" +#include "objbase.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#endif + +TShellExtensionClient::TShellExtensionClient() : + m_piShellExtControl(NULL) +{ +} + +TShellExtensionClient::~TShellExtensionClient() +{ + FreeControlInterface(); +} + +HRESULT TShellExtensionClient::RegisterShellExtDll(const CString& strPath, long lClientVersion, long& rlExtensionVersion, CString& rstrExtensionStringVersion) +{ + if(strPath.IsEmpty()) + return E_INVALIDARG; + + HRESULT hResult = S_OK; + + if(SUCCEEDED(hResult)) + hResult = CoInitializeEx(NULL, COINIT_MULTITHREADED); + + // get rid of the interface, so we can at least try to re-register + if(SUCCEEDED(hResult)) + FreeControlInterface(); + + // first try - load dll and register it manually. + // if failed - try by loading extension manually (would fail on vista when running as user) + if(SUCCEEDED(hResult)) + { + HRESULT (STDAPICALLTYPE *pfn)(void); + HINSTANCE hMod = LoadLibrary(strPath); // load the dll + if(hMod == NULL) + hResult = HRESULT_FROM_WIN32(GetLastError()); + if(SUCCEEDED(hResult) && !hMod) + hResult = E_FAIL; + if(SUCCEEDED(hResult)) + { + (FARPROC&)pfn = GetProcAddress(hMod, "DllRegisterServer"); + if(pfn == NULL) + hResult = E_FAIL; + if(SUCCEEDED(hResult)) + hResult = (*pfn)(); + + CoFreeLibrary(hMod); + } + CoUninitialize(); + } + + // if previous operation failed (ie. vista system) - try running regsvr32 with elevated privileges + if(SCODE_CODE(hResult) == ERROR_ACCESS_DENIED) + { + // try with regsvr32 + SHELLEXECUTEINFO sei; + memset(&sei, 0, sizeof(sei)); + sei.cbSize = sizeof(sei); + sei.fMask = SEE_MASK_UNICODE; + sei.lpVerb = _T("runas"); + sei.lpFile = _T("regsvr32.exe"); + CString strParams = CString(_T(" \"")) + strPath + CString(_T("\"")); + sei.lpParameters = strParams; + sei.nShow = SW_SHOW; + + if(!ShellExecuteEx(&sei)) + hResult = E_FAIL; + else + hResult = S_OK; + } + + if(SUCCEEDED(hResult)) + hResult = EnableExtensionIfCompatible(lClientVersion, rlExtensionVersion, rstrExtensionStringVersion); + + return hResult; +} + +HRESULT TShellExtensionClient::UnRegisterShellExtDll(const CString& strPath) +{ + if(strPath.IsEmpty()) + return E_INVALIDARG; + + HRESULT hResult = S_OK; + + if(SUCCEEDED(hResult)) + hResult = CoInitializeEx(NULL, COINIT_MULTITHREADED); + + // get rid of the interface if unregistering + if(SUCCEEDED(hResult)) + FreeControlInterface(); + + // first try - load dll and register it manually. + // if failed - try by loading extension manually (would fail on vista when running as user) + if(SUCCEEDED(hResult)) + { + HRESULT (STDAPICALLTYPE *pfn)(void); + HINSTANCE hMod = LoadLibrary(strPath); // load the dll + if(hMod == NULL) + hResult = HRESULT_FROM_WIN32(GetLastError()); + if(SUCCEEDED(hResult) && !hMod) + hResult = E_FAIL; + if(SUCCEEDED(hResult)) + { + (FARPROC&)pfn = GetProcAddress(hMod, "DllUnregisterServer"); + if(pfn == NULL) + hResult = E_FAIL; + if(SUCCEEDED(hResult)) + hResult = (*pfn)(); + + CoFreeLibrary(hMod); + } + CoUninitialize(); + } + + // if previous operation failed (ie. vista system) - try running regsvr32 with elevated privileges + if(SCODE_CODE(hResult) == ERROR_ACCESS_DENIED) + { + // try with regsvr32 + SHELLEXECUTEINFO sei; + memset(&sei, 0, sizeof(sei)); + sei.cbSize = sizeof(sei); + sei.fMask = SEE_MASK_UNICODE; + sei.lpVerb = _T("runas"); + sei.lpFile = _T("regsvr32.exe"); + CString strParams = CString(_T("/u \"")) + strPath + CString(_T("\"")); + sei.lpParameters = strParams; + sei.nShow = SW_SHOW; + + if(!ShellExecuteEx(&sei)) + hResult = E_FAIL; + else + hResult = S_OK; + } + + return hResult; +} + +HRESULT TShellExtensionClient::EnableExtensionIfCompatible(long lClientVersion, long& rlExtensionVersion, CString& rstrExtensionStringVersion) +{ + rlExtensionVersion = 0; + rstrExtensionStringVersion.Empty(); + + BSTR bstrVersion = NULL; + + HRESULT hResult = RetrieveControlInterface(); + if(SUCCEEDED(hResult) && !m_piShellExtControl) + hResult = E_FAIL; + if(SUCCEEDED(hResult)) + hResult = m_piShellExtControl->GetVersion(&rlExtensionVersion, &bstrVersion); + if(SUCCEEDED(hResult)) + { + // enable or disable extension - currently we only support extension from strictly the same version as CH + hResult = m_piShellExtControl->SetFlags((lClientVersion == rlExtensionVersion) ? eShellExt_Enabled : 0, eShellExt_Enabled); + if(SUCCEEDED(hResult)) + hResult = S_OK; + } + else if(SUCCEEDED(hResult)) + hResult = S_FALSE; + + // do not overwrite S_OK/S_FALSE status after this line - it needs to be propagated upwards + if(bstrVersion) + { + rstrExtensionStringVersion = bstrVersion; + ::SysFreeString(bstrVersion); + } + + return hResult; +} + +void TShellExtensionClient::Close() +{ + FreeControlInterface(); +} + +HRESULT TShellExtensionClient::RetrieveControlInterface() +{ + HRESULT hResult = CoInitializeEx(NULL, COINIT_MULTITHREADED); + if(SUCCEEDED(hResult)) + hResult = CoCreateInstance(CLSID_CShellExtControl, NULL, CLSCTX_ALL, IID_IShellExtControl, (void**)&m_piShellExtControl); + if(SUCCEEDED(hResult) && !m_piShellExtControl) + hResult = E_FAIL; + + return hResult; +} + +void TShellExtensionClient::FreeControlInterface() +{ + if(m_piShellExtControl) + { + m_piShellExtControl->Release(); + m_piShellExtControl = NULL; + } +} Index: src/ch/TShellExtensionClient.h =================================================================== diff -u --- src/ch/TShellExtensionClient.h (revision 0) +++ src/ch/TShellExtensionClient.h (revision 3cd8d4a64a63e4fb32d7dc96e46789c713698435) @@ -0,0 +1,48 @@ +/*************************************************************************** +* Copyright (C) 2001-2008 by J�zef Starosczyk * +* ixen@copyhandler.com * +* * +* This program is free software; you can redistribute it and/or modify * +* it under the terms of the GNU Library General Public License * +* (version 2) as published by the Free Software Foundation; * +* * +* This program is distributed in the hope that it will be useful, * +* but WITHOUT ANY WARRANTY; without even the implied warranty of * +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * +* GNU General Public License for more details. * +* * +* You should have received a copy of the GNU Library General Public * +* License along with this program; if not, write to the * +* Free Software Foundation, Inc., * +* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * +***************************************************************************/ +#ifndef __TSHELLEXTENSIONCLIENT_H__ +#define __TSHELLEXTENSIONCLIENT_H__ + +#include "../chext/chext.h" + +class TShellExtensionClient +{ +public: + TShellExtensionClient(); + ~TShellExtensionClient(); + + // registers or unregisters shell extension + HRESULT RegisterShellExtDll(const CString& strPath, long lClientVersion, long& rlExtensionVersion, CString& rstrExtensionStringVersion); + HRESULT UnRegisterShellExtDll(const CString& strPath); + + // enables the extension if compatible with the client (CH) version + // returns S_OK if enabled, S_FALSE if not + HRESULT EnableExtensionIfCompatible(long lClientVersion, long& rlExtensionVersion, CString& rstrExtensionStringVersion); + + void Close(); + +private: + HRESULT RetrieveControlInterface(); + void FreeControlInterface(); + +private: + IShellExtControl* m_piShellExtControl; +}; + +#endif \ No newline at end of file Index: src/ch/ch.cpp =================================================================== diff -u -rb684bec49aaaea4b89ab2e599497f4085d8698a3 -r3cd8d4a64a63e4fb32d7dc96e46789c713698435 --- src/ch/ch.cpp (.../ch.cpp) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) +++ src/ch/ch.cpp (.../ch.cpp) (revision 3cd8d4a64a63e4fb32d7dc96e46789c713698435) @@ -83,7 +83,6 @@ } CCopyHandlerApp::CCopyHandlerApp() : - m_piShellExtControl(NULL), m_hMapObject(NULL), m_pMainWindow(NULL) { @@ -105,12 +104,6 @@ delete m_pMainWindow; m_pMainWnd=NULL; } - - if(m_piShellExtControl) - { - m_piShellExtControl->Release(); - m_piShellExtControl = NULL; - } } CCopyHandlerApp& GetApp() @@ -335,40 +328,13 @@ LOG_INFO(_T("Checking shell extension compatibility")); - // calculate ch version - long lCHVersion = PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4; + InitShellExtension(); - // check the version of shell extension - LONG lVersion = 0; - BSTR bstrVersion = NULL; - - hResult = CoCreateInstance(CLSID_CShellExtControl, NULL, CLSCTX_ALL, IID_IShellExtControl, (void**)&m_piShellExtControl); - if(SUCCEEDED(hResult) && !m_piShellExtControl) - hResult = E_FAIL; - if(SUCCEEDED(hResult)) - hResult = m_piShellExtControl->GetVersion(&lVersion, &bstrVersion); - if(SUCCEEDED(hResult) && lVersion == lCHVersion) - hResult = m_piShellExtControl->SetFlags(eShellExt_Enabled, eShellExt_Enabled); - if(FAILED(hResult) || lCHVersion != lVersion) - { - CString strMsg; - strMsg.Format(_T("Shell extension has different version (0x%lx) than Copy Handler (0x%lx). Shell extension will be disabled."), lVersion, lCHVersion); - - LOG_WARNING(strMsg); - MsgBox(IDS_SHELL_EXTENSION_MISMATCH_STRING); - - if(m_piShellExtControl) - m_piShellExtControl->SetFlags(0, eShellExt_Enabled); - } - - if(bstrVersion) - ::SysFreeString(bstrVersion); - // ================================= Initial settings ======================================== LOG_INFO(_T("Applying initial settings")); // set this process priority class - HANDLE hProcess=GetCurrentProcess(); + HANDLE hProcess = GetCurrentProcess(); ::SetPriorityClass(hProcess, GetPropValue(rCfg)); #ifndef _DEBUG // for easier writing the program - doesn't collide with std CH @@ -391,6 +357,110 @@ return TRUE; } +void CCopyHandlerApp::InitShellExtension() +{ + // validate ch version against extension version + CString strExtensionStringVersion; + long lExtensionVersion = 0; + int iDlgResult = IDNO; + + // first try to just enable the extension (assume that it has already been registered) + HRESULT hResult = m_tShellExtClient.EnableExtensionIfCompatible(PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4, lExtensionVersion, strExtensionStringVersion); + if(FAILED(hResult)) + { + CString strMsg; + strMsg.Format(_T("Shell extension is not registered.")); + LOG_WARNING(strMsg); + + iDlgResult = MsgBox(IDS_SHELL_EXTENSION_UNREGISTERED_STRING, MB_ICONWARNING | MB_YESNO); + } + else if(hResult == S_FALSE) + { + CString strMsg; + strMsg.Format(_T("Shell extension has different version (0x%lx) than Copy Handler (0x%lx)."), lExtensionVersion, PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4); + LOG_WARNING(strMsg); + + iDlgResult = MsgBox(IDS_SHELL_EXTENSION_MISMATCH_STRING, MB_ICONWARNING | MB_YESNO); + } + + // we didn't succeed, but want to fix this + if(iDlgResult == IDYES) + { + // try to register the extension + RegisterShellExtension(); + } +} + +void CCopyHandlerApp::RegisterShellExtension() +{ + CString strPath = CString(GetProgramPath()) + _T("\\"); + +#ifdef _WIN64 + strPath += _T("chext64.dll"); +#else + strPath += _T("chext.dll"); +#endif + + long lExtensionVersion = 0; + CString strExtensionVersion; + + HRESULT hResult = m_tShellExtClient.RegisterShellExtDll(strPath, PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4, + lExtensionVersion, strExtensionVersion); + if(FAILED(hResult)) + { + // normal failure + TCHAR szStr[256]; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hResult, 0, szStr, 256, NULL); + while(szStr[_tcslen(szStr) - 1] == _T('\n') || szStr[_tcslen(szStr) - 1] == _T('\r') || szStr[_tcslen(szStr) - 1] == _T('.')) + szStr[_tcslen(szStr)-1] = _T('\0'); + + ictranslate::CFormat fmt(GetResManager().LoadString(IDS_REGISTERERR_STRING)); + fmt.SetParam(_T("%errno"), (ulong_t)hResult); + fmt.SetParam(_T("%errdesc"), szStr); + AfxMessageBox(fmt, MB_ICONERROR | MB_OK); + } + else if(hResult == S_FALSE) + { + // registered ok, but incompatible versions - probably restart required + CString strMsg; + strMsg.Format(_T("Registration succeeded, but still the shell extension has different version (0x%lx) than Copy Handler (0x%lx)."), lExtensionVersion, PRODUCT_VERSION1 << 24 | PRODUCT_VERSION2 << 16 | PRODUCT_VERSION3 << 8 | PRODUCT_VERSION4); + LOG_WARNING(strMsg); + + MsgBox(IDS_SHELL_EXTENSION_REGISTERED_MISMATCH_STRING, MB_ICONWARNING | MB_OK); + } + else if(hResult == S_OK) + MsgBox(IDS_REGISTEROK_STRING, MB_ICONINFORMATION | MB_OK); +} + +void CCopyHandlerApp::UnregisterShellExtension() +{ + CString strPath = CString(GetProgramPath()) + _T("\\"); + +#ifdef _WIN64 + strPath += _T("chext64.dll"); +#else + strPath += _T("chext.dll"); +#endif + + HRESULT hResult = m_tShellExtClient.UnRegisterShellExtDll(strPath); + if(FAILED(hResult)) + { + TCHAR szStr[256]; + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, hResult, 0, szStr, 256, NULL); + while (szStr[_tcslen(szStr)-1] == _T('\n') || szStr[_tcslen(szStr)-1] == _T('\r') || szStr[_tcslen(szStr)-1] == _T('.')) + szStr[_tcslen(szStr)-1] = _T('\0'); + + ictranslate::CFormat fmt(GetResManager().LoadString(IDS_UNREGISTERERR_STRING)); + fmt.SetParam(_T("%errno"), (ulong_t)hResult); + fmt.SetParam(_T("%errdesc"), szStr); + + AfxMessageBox(fmt, MB_ICONERROR | MB_OK); + } + else if(hResult == S_OK) + MsgBox(IDS_UNREGISTEROK_STRING, MB_ICONINFORMATION | MB_OK); +} + +/* bool CCopyHandlerApp::IsShellExtEnabled() const { if(m_piShellExtControl) @@ -402,6 +472,7 @@ } return false; } +*/ void CCopyHandlerApp::OnConfigNotify(const std::set& setPropNames) { @@ -519,12 +590,9 @@ int CCopyHandlerApp::ExitInstance() { LOG_INFO(_T("Pre-exit step - releasing shell extension")); - if(m_piShellExtControl) - { - m_piShellExtControl->Release(); - m_piShellExtControl = NULL; - } + m_tShellExtClient.Close(); + LOG_INFO(_T("Pre-exit step - uninitializing COM")); CoUninitialize(); Index: src/ch/ch.h =================================================================== diff -u -rb684bec49aaaea4b89ab2e599497f4085d8698a3 -r3cd8d4a64a63e4fb32d7dc96e46789c713698435 --- src/ch/ch.h (.../ch.h) (revision b684bec49aaaea4b89ab2e599497f4085d8698a3) +++ src/ch/ch.h (.../ch.h) (revision 3cd8d4a64a63e4fb32d7dc96e46789c713698435) @@ -26,13 +26,11 @@ #include "resource.h" // main symbols #include "AppHelper.h" #include "CfgProperties.h" -#include "../chext/chext.h" #include "../libicpf/log.h" #include "../libictranslate/ResourceManager.h" #include "../libchcore/TConfig.h" +#include "TShellExtensionClient.h" -using namespace std; - ///////////////////////////////////////////////////////////////////////////// // CCopyHandlerApp: // See CopyHandler.cpp for the implementation of this class @@ -58,7 +56,8 @@ friend ictranslate::CResourceManager& GetResManager(); friend chcore::TConfig& GetConfig(); - bool IsShellExtEnabled() const; + void RegisterShellExtension(); + void UnregisterShellExtension(); void OnConfigNotify(const std::set& setPropNames); void OnResManNotify(UINT uiType); @@ -67,9 +66,11 @@ bool UpdateHelpPaths(); HWND HHelp(HWND hwndCaller, LPCTSTR pszFile, UINT uCommand, DWORD_PTR dwData); + void InitShellExtension(); + protected: HANDLE m_hMapObject; - IShellExtControl* m_piShellExtControl; + TShellExtensionClient m_tShellExtClient; CWnd *m_pMainWindow; Index: src/ch/ch.rc =================================================================== diff -u -r0a673d59b6baab3d616ce2570e5bf63378fa7e3c -r3cd8d4a64a63e4fb32d7dc96e46789c713698435 --- src/ch/ch.rc (.../ch.rc) (revision 0a673d59b6baab3d616ce2570e5bf63378fa7e3c) +++ src/ch/ch.rc (.../ch.rc) (revision 3cd8d4a64a63e4fb32d7dc96e46789c713698435) @@ -79,8 +79,8 @@ BEGIN MENUITEM "&Check for updates...", ID_POPUP_CHECKFORUPDATES MENUITEM SEPARATOR - MENUITEM "&Register shell extension dll", ID_POPUP_REGISTERDLL - MENUITEM "&Unregister shell extension dll", ID_POPUP_UNREGISTERDLL + MENUITEM "&Enable integration with system", ID_POPUP_REGISTERDLL + MENUITEM "&Disable integration with system", ID_POPUP_UNREGISTERDLL END MENUITEM SEPARATOR MENUITEM "&Options...", ID_POPUP_OPTIONS @@ -636,11 +636,11 @@ STRINGTABLE BEGIN IDS_ONECOPY_STRING "Cannot run the second instance of this program" - IDS_REGISTEROK_STRING "Library chext.dll was registered successfully" - IDS_REGISTERERR_STRING "Encountered error while trying to register library chext.dll\nError #%errno (%errdesc)." - IDS_UNREGISTEROK_STRING "Library chext.dll was unregistered successfully" + IDS_REGISTEROK_STRING "Integration with system enabled successfully." + IDS_REGISTERERR_STRING "Encountered an error while trying to enable integration with system.\nError #%errno (%errdesc)." + IDS_UNREGISTEROK_STRING "Integration with system disabled successfully." IDS_UNREGISTERERR_STRING - "Encountered error while trying to unregister library chext.dll\nError #%errno (%errdesc)." + "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." END @@ -1054,8 +1054,9 @@ "There was an error when trying to retrieve version information from the official web page (%errdesc)." IDS_UPDATER_WAITING_STRING "Please wait for the connection with %site to be established..." - IDS_SHELL_EXTENSION_MISMATCH_STRING - "CH shell extension registered on your system does not match the Copy Handler version you are currently running.\nPlease re-register the shell extension using Copy Handler context menu and reboot your system to make sure the proper version is loaded.\n\nCopy Handler shell extension will be disabled." + IDS_SHELL_EXTENSION_MISMATCH_STRING "Copy Handler encountered incompatible version of component enabling integration with system installed on your system.\nWould you like to update it now (requires administrative rights)?" + IDS_SHELL_EXTENSION_UNREGISTERED_STRING "Copy Handler's component enabling integration with system is disabled.\nDo you want to enable it now (requires administrative rights)?" + IDS_SHELL_EXTENSION_REGISTERED_MISMATCH_STRING "Copy Handler's component enabling integration with system was updated.\nPlease reboot your system for changes to take effect." END STRINGTABLE Index: src/ch/ch.vc90.vcproj =================================================================== diff -u -r541933027e84c7a2acf505547170f5da4d87aa82 -r3cd8d4a64a63e4fb32d7dc96e46789c713698435 --- src/ch/ch.vc90.vcproj (.../ch.vc90.vcproj) (revision 541933027e84c7a2acf505547170f5da4d87aa82) +++ src/ch/ch.vc90.vcproj (.../ch.vc90.vcproj) (revision 3cd8d4a64a63e4fb32d7dc96e46789c713698435) @@ -595,14 +595,6 @@ > - - - - @@ -943,6 +935,18 @@ + + + + + +