| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520 | 
							- /*=========================================================================
 
-   Program:   CMake - Cross-Platform Makefile Generator
 
-   Module:    $RCSfile$
 
-   Language:  C++
 
-   Date:      $Date$
 
-   Version:   $Revision$
 
-   Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
 
-   See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
 
-      This software is distributed WITHOUT ANY WARRANTY; without even
 
-      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 
-      PURPOSE.  See the above copyright notices for more information.
 
- =========================================================================*/
 
- #include "cmCallVisualStudioMacro.h"
 
- #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>
 
- //----------------------------------------------------------------------------
 
- ///! 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 oss; \
 
-       oss.flags(std::ios::hex); \
 
-       oss << context << " failed HRESULT, hr = 0x" << hr << std::endl; \
 
-       oss.flags(std::ios::dec); \
 
-       oss << __FILE__ << "(" << __LINE__ << ")"; \
 
-       cmSystemTools::Message(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 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";
 
-     hr = vsIDE->GetIDsOfNames(IID_NULL, &name, 1,
 
-            LOCALE_USER_DEFAULT, &dispid);
 
-     ReportHRESULT(hr, "GetIDsOfNames(ExecuteCommand)");
 
-     if (SUCCEEDED(hr))
 
-       {
 
-       VARIANTARG vargs[2];
 
-       DISPPARAMS params;
 
-       VARIANT result;
 
-       EXCEPINFO excep;
 
-       UINT arg = (UINT) -1;
 
-       // No VariantInit or VariantClear calls are necessary for
 
-       // these two vargs. They are both local _bstr_t variables
 
-       // that remain in scope for the duration of the Invoke call.
 
-       //
 
-       V_VT(&vargs[1]) = VT_BSTR;
 
-       V_BSTR(&vargs[1]) = macroName;
 
-       V_VT(&vargs[0]) = VT_BSTR;
 
-       V_BSTR(&vargs[0]) = macroArgs;
 
-       params.rgvarg = &vargs[0];
 
-       params.rgdispidNamedArgs = 0;
 
-       params.cArgs = sizeof(vargs)/sizeof(vargs[0]);
 
-       params.cNamedArgs = 0;
 
-       VariantInit(&result);
 
-       memset(&excep, 0, sizeof(excep));
 
-       hr = vsIDE->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
 
-         DISPATCH_METHOD, ¶ms, &result, &excep, &arg);
 
-       std::ostringstream oss;
 
-       oss << std::endl;
 
-       oss << "Invoke(ExecuteCommand)" << std::endl;
 
-       oss << "  Macro: " << macro.c_str() << std::endl;
 
-       oss << "  Args: " << args.c_str() << std::endl;
 
-       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;
 
-           }
 
-         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 hr = E_POINTER;
 
-   if (0 != vsIDE)
 
-     {
 
-     DISPID dispid = (DISPID) -1;
 
-     OLECHAR *name = L"Solution";
 
-     hr = vsIDE->GetIDsOfNames(IID_NULL, &name, 1,
 
-            LOCALE_USER_DEFAULT, &dispid);
 
-     ReportHRESULT(hr, "GetIDsOfNames(Solution)");
 
-     if (SUCCEEDED(hr))
 
-       {
 
-       DISPPARAMS params;
 
-       VARIANT result;
 
-       EXCEPINFO excep;
 
-       UINT arg = (UINT) -1;
 
-       params.rgvarg = 0;
 
-       params.rgdispidNamedArgs = 0;
 
-       params.cArgs = 0;
 
-       params.cNamedArgs = 0;
 
-       VariantInit(&result);
 
-       memset(&excep, 0, sizeof(excep));
 
-       hr = vsIDE->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
 
-         DISPATCH_PROPERTYGET, ¶ms, &result, &excep, &arg);
 
-       ReportHRESULT(hr, "Invoke(Solution)");
 
-       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 hr = E_POINTER;
 
-   if (0 != vsSolution)
 
-     {
 
-     DISPID dispid = (DISPID) -1;
 
-     OLECHAR *name = L"FullName";
 
-     hr = vsSolution->GetIDsOfNames(IID_NULL, &name, 1,
 
-            LOCALE_USER_DEFAULT, &dispid);
 
-     ReportHRESULT(hr, "GetIDsOfNames(FullName)");
 
-     if (SUCCEEDED(hr))
 
-       {
 
-       DISPPARAMS params;
 
-       VARIANT result;
 
-       EXCEPINFO excep;
 
-       UINT arg = (UINT) -1;
 
-       params.rgvarg = 0;
 
-       params.rgdispidNamedArgs = 0;
 
-       params.cArgs = 0;
 
-       params.cNamedArgs = 0;
 
-       VariantInit(&result);
 
-       memset(&excep, 0, sizeof(excep));
 
-       hr = vsSolution->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT,
 
-         DISPATCH_PROPERTYGET, ¶ms, &result, &excep, &arg);
 
-       ReportHRESULT(hr, "Invoke(FullName)");
 
-       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)
 
- {
 
-   IDispatchPtr vsSolution;
 
-   HRESULT hr = GetSolutionObject(vsIDE, vsSolution);
 
-   ReportHRESULT(hr, "GetSolutionObject");
 
-   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)
 
- {
 
-   // mrot == Map of the Running Object Table
 
-   IRunningObjectTablePtr runningObjectTable;
 
-   IEnumMonikerPtr monikerEnumerator;
 
-   IMonikerPtr moniker;
 
-   ULONG numFetched = 0;
 
-   HRESULT hr = GetRunningObjectTable(0, &runningObjectTable);
 
-   ReportHRESULT(hr, "GetRunningObjectTable");
 
-   if(SUCCEEDED(hr))
 
-     {
 
-     hr = runningObjectTable->EnumRunning(&monikerEnumerator);
 
-     ReportHRESULT(hr, "EnumRunning");
 
-     }
 
-   if(SUCCEEDED(hr))
 
-     {
 
-     hr = monikerEnumerator->Reset();
 
-     ReportHRESULT(hr, "Reset");
 
-     }
 
-   if(SUCCEEDED(hr))
 
-     {
 
-     while (S_OK == monikerEnumerator->Next(1, &moniker, &numFetched))
 
-       {
 
-       std::string runningObjectName;
 
-       IUnknownPtr runningObjectVal;
 
-       IBindCtxPtr ctx;
 
-       hr = CreateBindCtx(0, &ctx);
 
-       ReportHRESULT(hr, "CreateBindCtx");
 
-       if(SUCCEEDED(hr))
 
-         {
 
-         LPOLESTR displayName = 0;
 
-         hr = moniker->GetDisplayName(ctx, 0, &displayName);
 
-         ReportHRESULT(hr, "GetDisplayName");
 
-         if (displayName)
 
-           {
 
-           runningObjectName = (std::string) (_bstr_t) displayName;
 
-           CoTaskMemFree(displayName);
 
-           }
 
-         hr = runningObjectTable->GetObject(moniker, &runningObjectVal);
 
-         ReportHRESULT(hr, "GetObject");
 
-         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)
 
- {
 
-   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:
 
-   std::string s1 = cmSystemTools::LowerCase(slnFile);
 
-   std::string s2 = cmSystemTools::LowerCase(slnName);
 
-   cmSystemTools::ConvertToUnixSlashes(s1);
 
-   cmSystemTools::ConvertToUnixSlashes(s2);
 
-   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)
 
- {
 
-   std::map<std::string, IUnknownPtr> mrot;
 
-   HRESULT hr = GetRunningInstances(mrot);
 
-   ReportHRESULT(hr, "GetRunningInstances");
 
-   if(SUCCEEDED(hr))
 
-     {
 
-     std::map<std::string, IUnknownPtr>::iterator it;
 
-     for(it = mrot.begin(); it != mrot.end(); ++it)
 
-       {
 
-       if (cmSystemTools::StringStartsWith(it->first.c_str(),
 
-         "!VisualStudio.DTE."))
 
-         {
 
-         IDispatchPtr disp(it->second);
 
-         if (disp != (IDispatch*) 0)
 
-           {
 
-           std::string slnName;
 
-           hr = GetIDESolutionFullName(disp, slnName);
 
-           ReportHRESULT(hr, "GetIDESolutionFullName");
 
-           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: "
 
-             //          << (IUnknown*) it->second << std::endl;
 
-             //std::cout << "  slnFile: " << slnFile << std::endl;
 
-             //std::cout << "  slnName: " << slnName << std::endl;
 
-             }
 
-           }
 
-         }
 
-       }
 
-     }
 
-   return hr;
 
- }
 
- #endif  //defined(HAVE_COMDEF_H)
 
- //----------------------------------------------------------------------------
 
- int cmCallVisualStudioMacro::GetNumberOfRunningVisualStudioInstances(
 
-   const std::string& slnFile)
 
- {
 
-   int count = 0;
 
-   LogErrorsAsMessages = false;
 
- #if defined(HAVE_COMDEF_H)
 
-   HRESULT hr = CoInitialize(0);
 
-   ReportHRESULT(hr, "CoInitialize");
 
-   if(SUCCEEDED(hr))
 
-     {
 
-     std::vector<IDispatchPtr> instances;
 
-     hr = FindVisualStudioInstances(slnFile, instances);
 
-     ReportHRESULT(hr, "FindVisualStudioInstances");
 
-     if(SUCCEEDED(hr))
 
-       {
 
-       count = static_cast<int>(instances.size());
 
-       }
 
-     // Force release all COM pointers before CoUninitialize:
 
-     instances.clear();
 
-     CoUninitialize();
 
-     }
 
- #else
 
-   (void)slnFile;
 
- #endif
 
-   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 err = 1; // no comdef.h
 
-   LogErrorsAsMessages = logErrorsAsMessages;
 
- #if defined(HAVE_COMDEF_H)
 
-   err = 2; // error initializing
 
-   HRESULT hr = CoInitialize(0);
 
-   ReportHRESULT(hr, "CoInitialize");
 
-   if(SUCCEEDED(hr))
 
-     {
 
-     std::vector<IDispatchPtr> instances;
 
-     hr = FindVisualStudioInstances(slnFile, instances);
 
-     ReportHRESULT(hr, "FindVisualStudioInstances");
 
-     if(SUCCEEDED(hr))
 
-       {
 
-       err = 0; // no error
 
-       std::vector<IDispatchPtr>::iterator it;
 
-       for(it = instances.begin(); it != instances.end(); ++it)
 
-         {
 
-         hr = InstanceCallMacro(*it, macro, args);
 
-         ReportHRESULT(hr, "InstanceCallMacro");
 
-         if (FAILED(hr))
 
-           {
 
-           err = 3; // error attempting to call the macro
 
-           }
 
-         }
 
-       if(0 == instances.size())
 
-         {
 
-         // no instances to call
 
-         //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)
 
-     {
 
-     cmSystemTools::Message("cmCallVisualStudioMacro::CallMacro is not "
 
-       "supported on this platform");
 
-     }
 
- #endif
 
-   if (err && LogErrorsAsMessages)
 
-     {
 
-     std::ostringstream oss;
 
-     oss << "cmCallVisualStudioMacro::CallMacro failed, err = " << err;
 
-     cmSystemTools::Message(oss.str().c_str());
 
-     }
 
-   return 0;
 
- }
 
 
  |