Using the given instance of Visual Studio, call the named macro
| 54 | |
| 55 | //! Using the given instance of Visual Studio, call the named macro |
| 56 | HRESULT InstanceCallMacro(IDispatch* vsIDE, std::string const& macro, |
| 57 | std::string const& args) |
| 58 | { |
| 59 | HRESULT hr = E_POINTER; |
| 60 | |
| 61 | _bstr_t macroName(macro.c_str()); |
| 62 | _bstr_t macroArgs(args.c_str()); |
| 63 | |
| 64 | if (0 != vsIDE) { |
| 65 | DISPID dispid = (DISPID)-1; |
| 66 | wchar_t execute_command[] = L"ExecuteCommand"; |
| 67 | OLECHAR* name = execute_command; |
| 68 | |
| 69 | hr = |
| 70 | vsIDE->GetIDsOfNames(IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispid); |
| 71 | ReportHRESULT(hr, "GetIDsOfNames(ExecuteCommand)"); |
| 72 | |
| 73 | if (SUCCEEDED(hr)) { |
| 74 | VARIANTARG vargs[2]; |
| 75 | DISPPARAMS params; |
| 76 | VARIANT result; |
| 77 | EXCEPINFO excep; |
| 78 | UINT arg = (UINT)-1; |
| 79 | |
| 80 | // No VariantInit or VariantClear calls are necessary for |
| 81 | // these two vargs. They are both local _bstr_t variables |
| 82 | // that remain in scope for the duration of the Invoke call. |
| 83 | // |
| 84 | V_VT(&vargs[1]) = VT_BSTR; |
| 85 | V_BSTR(&vargs[1]) = macroName; |
| 86 | V_VT(&vargs[0]) = VT_BSTR; |
| 87 | V_BSTR(&vargs[0]) = macroArgs; |
| 88 | |
| 89 | params.rgvarg = &vargs[0]; |
| 90 | params.rgdispidNamedArgs = 0; |
| 91 | params.cArgs = sizeof(vargs) / sizeof(vargs[0]); |
| 92 | params.cNamedArgs = 0; |
| 93 | |
| 94 | VariantInit(&result); |
| 95 | |
| 96 | memset(&excep, 0, sizeof(excep)); |
| 97 | |
| 98 | hr = vsIDE->Invoke(dispid, IID_NULL, LOCALE_USER_DEFAULT, |
| 99 | DISPATCH_METHOD, ¶ms, &result, &excep, &arg); |
| 100 | |
| 101 | std::ostringstream oss; |
| 102 | /* clang-format off */ |
| 103 | oss << "\nInvoke(ExecuteCommand)\n" |
| 104 | " Macro: " << macro << "\n" |
| 105 | " Args: " << args << '\n'; |
| 106 | /* clang-format on */ |
| 107 | |
| 108 | if (DISP_E_EXCEPTION == hr) { |
| 109 | /* clang-format off */ |
| 110 | oss << "DISP_E_EXCEPTION EXCEPINFO:" << excep.wCode << "\n" |
| 111 | " wCode: " << excep.wCode << "\n" |
| 112 | " wReserved: " << excep.wReserved << '\n'; |
| 113 | /* clang-format on */ |