diff options
Diffstat (limited to 'Source/cmCallVisualStudioMacro.cxx')
-rw-r--r-- | Source/cmCallVisualStudioMacro.cxx | 322 |
1 files changed, 129 insertions, 193 deletions
diff --git a/Source/cmCallVisualStudioMacro.cxx b/Source/cmCallVisualStudioMacro.cxx index 9cc5a69..e608d6b 100644 --- a/Source/cmCallVisualStudioMacro.cxx +++ b/Source/cmCallVisualStudioMacro.cxx @@ -13,86 +13,73 @@ #include "cmSystemTools.h" - #if defined(_MSC_VER) #define HAVE_COMDEF_H #endif - // Just for this file: // static bool LogErrorsAsMessages; - #if defined(HAVE_COMDEF_H) - #include <comdef.h> - // Copied from a correct comdef.h to avoid problems with deficient versions // of comdef.h that exist in the wild... Fixes issue #7533. // #ifdef _NATIVE_WCHAR_T_DEFINED -# ifdef _DEBUG -# pragma comment(lib, "comsuppwd.lib") -# else -# pragma comment(lib, "comsuppw.lib") -# endif +#ifdef _DEBUG +#pragma comment(lib, "comsuppwd.lib") #else -# ifdef _DEBUG -# pragma comment(lib, "comsuppd.lib") -# else -# pragma comment(lib, "comsupp.lib") -# endif +#pragma comment(lib, "comsuppw.lib") +#endif +#else +#ifdef _DEBUG +#pragma comment(lib, "comsuppd.lib") +#else +#pragma comment(lib, "comsupp.lib") +#endif #endif - ///! Use ReportHRESULT to make a cmSystemTools::Message after calling ///! a COM method that may have failed. -#define ReportHRESULT(hr, context) \ - if (FAILED(hr)) \ - { \ - if (LogErrorsAsMessages) \ - { \ - std::ostringstream _hresult_oss; \ - _hresult_oss.flags(std::ios::hex); \ - _hresult_oss << context << " failed HRESULT, hr = 0x" \ - << hr << std::endl; \ - _hresult_oss.flags(std::ios::dec); \ - _hresult_oss << __FILE__ << "(" << __LINE__ << ")"; \ - cmSystemTools::Message(_hresult_oss.str().c_str()); \ - } \ - } - +#define ReportHRESULT(hr, context) \ + if (FAILED(hr)) { \ + if (LogErrorsAsMessages) { \ + std::ostringstream _hresult_oss; \ + _hresult_oss.flags(std::ios::hex); \ + _hresult_oss << context << " failed HRESULT, hr = 0x" << hr \ + << std::endl; \ + _hresult_oss.flags(std::ios::dec); \ + _hresult_oss << __FILE__ << "(" << __LINE__ << ")"; \ + cmSystemTools::Message(_hresult_oss.str().c_str()); \ + } \ + } ///! Using the given instance of Visual Studio, call the named macro -HRESULT InstanceCallMacro( - IDispatch* vsIDE, - const std::string& macro, - const std::string& args) +HRESULT InstanceCallMacro(IDispatch* vsIDE, const std::string& macro, + const std::string& args) { HRESULT hr = E_POINTER; _bstr_t macroName(macro.c_str()); _bstr_t macroArgs(args.c_str()); - if (0 != vsIDE) - { - DISPID dispid = (DISPID) -1; - OLECHAR *name = L"ExecuteCommand"; + if (0 != vsIDE) { + DISPID dispid = (DISPID)-1; + OLECHAR* name = L"ExecuteCommand"; - hr = vsIDE->GetIDsOfNames(IID_NULL, &name, 1, - LOCALE_USER_DEFAULT, &dispid); + hr = + vsIDE->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid); ReportHRESULT(hr, "GetIDsOfNames(ExecuteCommand)"); - if (SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { VARIANTARG vargs[2]; DISPPARAMS params; VARIANT result; EXCEPINFO excep; - UINT arg = (UINT) -1; + UINT arg = (UINT)-1; // No VariantInit or VariantClear calls are necessary for // these two vargs. They are both local _bstr_t variables @@ -105,7 +92,7 @@ HRESULT InstanceCallMacro( params.rgvarg = &vargs[0]; params.rgdispidNamedArgs = 0; - params.cArgs = sizeof(vargs)/sizeof(vargs[0]); + params.cArgs = sizeof(vargs) / sizeof(vargs[0]); params.cNamedArgs = 0; VariantInit(&result); @@ -113,7 +100,7 @@ HRESULT InstanceCallMacro( memset(&excep, 0, sizeof(excep)); hr = vsIDE->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, - DISPATCH_METHOD, ¶ms, &result, &excep, &arg); + DISPATCH_METHOD, ¶ms, &result, &excep, &arg); std::ostringstream oss; oss << std::endl; @@ -121,65 +108,56 @@ HRESULT InstanceCallMacro( oss << " Macro: " << macro.c_str() << std::endl; oss << " Args: " << args.c_str() << std::endl; - if (DISP_E_EXCEPTION == hr) - { + if (DISP_E_EXCEPTION == hr) { oss << "DISP_E_EXCEPTION EXCEPINFO:" << excep.wCode << std::endl; oss << " wCode: " << excep.wCode << std::endl; oss << " wReserved: " << excep.wReserved << std::endl; - if (excep.bstrSource) - { - oss << " bstrSource: " << - (const char*)(_bstr_t)excep.bstrSource << std::endl; - } - if (excep.bstrDescription) - { - oss << " bstrDescription: " << - (const char*)(_bstr_t)excep.bstrDescription << std::endl; - } - if (excep.bstrHelpFile) - { - oss << " bstrHelpFile: " << - (const char*)(_bstr_t)excep.bstrHelpFile << std::endl; - } + if (excep.bstrSource) { + oss << " bstrSource: " << (const char*)(_bstr_t)excep.bstrSource + << std::endl; + } + if (excep.bstrDescription) { + oss << " bstrDescription: " + << (const char*)(_bstr_t)excep.bstrDescription << std::endl; + } + if (excep.bstrHelpFile) { + oss << " bstrHelpFile: " << (const char*)(_bstr_t)excep.bstrHelpFile + << std::endl; + } oss << " dwHelpContext: " << excep.dwHelpContext << std::endl; oss << " pvReserved: " << excep.pvReserved << std::endl; oss << " pfnDeferredFillIn: " << excep.pfnDeferredFillIn << std::endl; oss << " scode: " << excep.scode << std::endl; - } + } std::string exstr(oss.str()); ReportHRESULT(hr, exstr.c_str()); VariantClear(&result); - } } + } return hr; } - ///! Get the Solution object from the IDE object -HRESULT GetSolutionObject( - IDispatch* vsIDE, - IDispatchPtr& vsSolution) +HRESULT GetSolutionObject(IDispatch* vsIDE, IDispatchPtr& vsSolution) { HRESULT hr = E_POINTER; - if (0 != vsIDE) - { - DISPID dispid = (DISPID) -1; - OLECHAR *name = L"Solution"; + if (0 != vsIDE) { + DISPID dispid = (DISPID)-1; + OLECHAR* name = L"Solution"; - hr = vsIDE->GetIDsOfNames(IID_NULL, &name, 1, - LOCALE_USER_DEFAULT, &dispid); + hr = + vsIDE->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid); ReportHRESULT(hr, "GetIDsOfNames(Solution)"); - if (SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { DISPPARAMS params; VARIANT result; EXCEPINFO excep; - UINT arg = (UINT) -1; + UINT arg = (UINT)-1; params.rgvarg = 0; params.rgdispidNamedArgs = 0; @@ -191,44 +169,38 @@ HRESULT GetSolutionObject( memset(&excep, 0, sizeof(excep)); hr = vsIDE->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, - DISPATCH_PROPERTYGET, ¶ms, &result, &excep, &arg); + DISPATCH_PROPERTYGET, ¶ms, &result, &excep, &arg); ReportHRESULT(hr, "Invoke(Solution)"); - if (SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { vsSolution = V_DISPATCH(&result); - } + } VariantClear(&result); - } } + } return hr; } - ///! Get the FullName property from the Solution object -HRESULT GetSolutionFullName( - IDispatch* vsSolution, - std::string& fullName) +HRESULT GetSolutionFullName(IDispatch* vsSolution, std::string& fullName) { HRESULT hr = E_POINTER; - if (0 != vsSolution) - { - DISPID dispid = (DISPID) -1; - OLECHAR *name = L"FullName"; + if (0 != vsSolution) { + DISPID dispid = (DISPID)-1; + OLECHAR* name = L"FullName"; - hr = vsSolution->GetIDsOfNames(IID_NULL, &name, 1, - LOCALE_USER_DEFAULT, &dispid); + hr = vsSolution->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, + &dispid); ReportHRESULT(hr, "GetIDsOfNames(FullName)"); - if (SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { DISPPARAMS params; VARIANT result; EXCEPINFO excep; - UINT arg = (UINT) -1; + UINT arg = (UINT)-1; params.rgvarg = 0; params.rgdispidNamedArgs = 0; @@ -240,41 +212,36 @@ HRESULT GetSolutionFullName( memset(&excep, 0, sizeof(excep)); hr = vsSolution->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, - DISPATCH_PROPERTYGET, ¶ms, &result, &excep, &arg); + DISPATCH_PROPERTYGET, ¶ms, &result, &excep, + &arg); ReportHRESULT(hr, "Invoke(FullName)"); - if (SUCCEEDED(hr)) - { - fullName = (std::string) (_bstr_t) V_BSTR(&result); - } + if (SUCCEEDED(hr)) { + fullName = (std::string)(_bstr_t)V_BSTR(&result); + } VariantClear(&result); - } } + } return hr; } - ///! Get the FullName property from the Solution object, given the IDE object -HRESULT GetIDESolutionFullName( - IDispatch* vsIDE, - std::string& fullName) +HRESULT GetIDESolutionFullName(IDispatch* vsIDE, std::string& fullName) { IDispatchPtr vsSolution; HRESULT hr = GetSolutionObject(vsIDE, vsSolution); ReportHRESULT(hr, "GetSolutionObject"); - if (SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { GetSolutionFullName(vsSolution, fullName); ReportHRESULT(hr, "GetSolutionFullName"); - } + } return hr; } - ///! Get all running objects from the Windows running object table. ///! Save them in a map by their display names. HRESULT GetRunningInstances(std::map<std::string, IUnknownPtr>& mrot) @@ -289,22 +256,18 @@ HRESULT GetRunningInstances(std::map<std::string, IUnknownPtr>& mrot) HRESULT hr = GetRunningObjectTable(0, &runningObjectTable); ReportHRESULT(hr, "GetRunningObjectTable"); - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { hr = runningObjectTable->EnumRunning(&monikerEnumerator); ReportHRESULT(hr, "EnumRunning"); - } + } - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { hr = monikerEnumerator->Reset(); ReportHRESULT(hr, "Reset"); - } + } - if(SUCCEEDED(hr)) - { - while (S_OK == monikerEnumerator->Next(1, &moniker, &numFetched)) - { + if (SUCCEEDED(hr)) { + while (S_OK == monikerEnumerator->Next(1, &moniker, &numFetched)) { std::string runningObjectName; IUnknownPtr runningObjectVal; IBindCtxPtr ctx; @@ -312,44 +275,37 @@ HRESULT GetRunningInstances(std::map<std::string, IUnknownPtr>& mrot) hr = CreateBindCtx(0, &ctx); ReportHRESULT(hr, "CreateBindCtx"); - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { LPOLESTR displayName = 0; hr = moniker->GetDisplayName(ctx, 0, &displayName); ReportHRESULT(hr, "GetDisplayName"); - if (displayName) - { - runningObjectName = (std::string) (_bstr_t) displayName; + if (displayName) { + runningObjectName = (std::string)(_bstr_t)displayName; CoTaskMemFree(displayName); - } + } hr = runningObjectTable->GetObject(moniker, &runningObjectVal); ReportHRESULT(hr, "GetObject"); - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { mrot.insert(std::make_pair(runningObjectName, runningObjectVal)); - } } + } numFetched = 0; moniker = 0; - } } + } return hr; } - ///! Do the two file names refer to the same Visual Studio solution? Or are ///! we perhaps looking for any and all solutions? -bool FilesSameSolution( - const std::string& slnFile, - const std::string& slnName) +bool FilesSameSolution(const std::string& slnFile, const std::string& slnName) { - if (slnFile == "ALL" || slnName == "ALL") - { + if (slnFile == "ALL" || slnName == "ALL") { return true; - } + } // Otherwise, make lowercase local copies, convert to Unix slashes, and // see if the resulting strings are the same: @@ -361,56 +317,47 @@ bool FilesSameSolution( return s1 == s2; } - ///! Find instances of Visual Studio with the given solution file ///! open. Pass "ALL" for slnFile to gather all running instances ///! of Visual Studio. -HRESULT FindVisualStudioInstances( - const std::string& slnFile, - std::vector<IDispatchPtr>& instances) +HRESULT FindVisualStudioInstances(const std::string& slnFile, + std::vector<IDispatchPtr>& instances) { std::map<std::string, IUnknownPtr> mrot; HRESULT hr = GetRunningInstances(mrot); ReportHRESULT(hr, "GetRunningInstances"); - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { std::map<std::string, IUnknownPtr>::iterator it; - for(it = mrot.begin(); it != mrot.end(); ++it) - { + for (it = mrot.begin(); it != mrot.end(); ++it) { if (cmSystemTools::StringStartsWith(it->first.c_str(), - "!VisualStudio.DTE.")) - { + "!VisualStudio.DTE.")) { IDispatchPtr disp(it->second); - if (disp != (IDispatch*) 0) - { + if (disp != (IDispatch*)0) { std::string slnName; hr = GetIDESolutionFullName(disp, slnName); ReportHRESULT(hr, "GetIDESolutionFullName"); - if (FilesSameSolution(slnFile, slnName)) - { + if (FilesSameSolution(slnFile, slnName)) { instances.push_back(disp); - //std::cout << "Found Visual Studio instance." << std::endl; - //std::cout << " ROT entry name: " << it->first << std::endl; - //std::cout << " ROT entry object: " + // std::cout << "Found Visual Studio instance." << std::endl; + // std::cout << " ROT entry name: " << it->first << std::endl; + // std::cout << " ROT entry object: " // << (IUnknown*) it->second << std::endl; - //std::cout << " slnFile: " << slnFile << std::endl; - //std::cout << " slnName: " << slnName << std::endl; - } + // std::cout << " slnFile: " << slnFile << std::endl; + // std::cout << " slnName: " << slnName << std::endl; } } } } + } return hr; } - -#endif //defined(HAVE_COMDEF_H) - +#endif // defined(HAVE_COMDEF_H) int cmCallVisualStudioMacro::GetNumberOfRunningVisualStudioInstances( const std::string& slnFile) @@ -423,22 +370,20 @@ int cmCallVisualStudioMacro::GetNumberOfRunningVisualStudioInstances( HRESULT hr = CoInitialize(0); ReportHRESULT(hr, "CoInitialize"); - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { std::vector<IDispatchPtr> instances; hr = FindVisualStudioInstances(slnFile, instances); ReportHRESULT(hr, "FindVisualStudioInstances"); - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { count = static_cast<int>(instances.size()); - } + } // Force release all COM pointers before CoUninitialize: instances.clear(); CoUninitialize(); - } + } #else (void)slnFile; #endif @@ -446,14 +391,12 @@ int cmCallVisualStudioMacro::GetNumberOfRunningVisualStudioInstances( return count; } - ///! Get all running objects from the Windows running object table. ///! Save them in a map by their display names. -int cmCallVisualStudioMacro::CallMacro( - const std::string& slnFile, - const std::string& macro, - const std::string& args, - const bool logErrorsAsMessages) +int cmCallVisualStudioMacro::CallMacro(const std::string& slnFile, + const std::string& macro, + const std::string& args, + const bool logErrorsAsMessages) { int err = 1; // no comdef.h @@ -465,60 +408,53 @@ int cmCallVisualStudioMacro::CallMacro( HRESULT hr = CoInitialize(0); ReportHRESULT(hr, "CoInitialize"); - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { std::vector<IDispatchPtr> instances; hr = FindVisualStudioInstances(slnFile, instances); ReportHRESULT(hr, "FindVisualStudioInstances"); - if(SUCCEEDED(hr)) - { + if (SUCCEEDED(hr)) { err = 0; // no error std::vector<IDispatchPtr>::iterator it; - for(it = instances.begin(); it != instances.end(); ++it) - { + for (it = instances.begin(); it != instances.end(); ++it) { hr = InstanceCallMacro(*it, macro, args); ReportHRESULT(hr, "InstanceCallMacro"); - if (FAILED(hr)) - { + if (FAILED(hr)) { err = 3; // error attempting to call the macro - } } + } - if(instances.empty()) - { + if (instances.empty()) { // no instances to call - //cmSystemTools::Message( + // cmSystemTools::Message( // "cmCallVisualStudioMacro::CallMacro no instances found to call", // "Warning"); - } } + } // Force release all COM pointers before CoUninitialize: instances.clear(); CoUninitialize(); - } + } #else (void)slnFile; (void)macro; (void)args; - if (LogErrorsAsMessages) - { + if (LogErrorsAsMessages) { cmSystemTools::Message("cmCallVisualStudioMacro::CallMacro is not " - "supported on this platform"); - } + "supported on this platform"); + } #endif - if (err && LogErrorsAsMessages) - { + if (err && LogErrorsAsMessages) { std::ostringstream oss; oss << "cmCallVisualStudioMacro::CallMacro failed, err = " << err; cmSystemTools::Message(oss.str().c_str()); - } + } return 0; } |