BOOL IsExcelThere() { IRunningObjectTable *pRot = NULL; ::GetRunningObjectTable(0, &pRot); IEnumMoniker *pEnum = NULL; pRot->EnumRunning(&pEnum); IMoniker* pMon[1] = { NULL }; ULONG fetched = 0; BOOL found = FALSE; while (pEnum->Next(1, pMon, &fetched) == 0) { IUnknown *pUnknown; pRot->GetObject(pMon[0], &pUnknown); IUnknown *pWorkbook; if (SUCCEEDED(pUnknown->QueryInterface(DIID__Workbook, (void **) &pWorkbook))) { found = TRUE; pWorkbook->Release(); break; } pUnknown->Release(); } if (pRot != NULL) pRot->Release(); if (pEnum != NULL) pEnum->Release(); return found; }
/** Accesses the correct visual studio instance if possible. */ bool AccessVisualStudio(CComPtr<EnvDTE::_DTE>& OutDTE, const FString& InSolutionPath, const TArray<FVSAccessorModule::VisualStudioLocation>& InLocations) { bool bSuccess = false; // Open the Running Object Table (ROT) IRunningObjectTable* RunningObjectTable; if (SUCCEEDED(GetRunningObjectTable(0, &RunningObjectTable)) && RunningObjectTable) { IEnumMoniker* MonikersTable; RunningObjectTable->EnumRunning(&MonikersTable); MonikersTable->Reset(); // Look for all visual studio instances in the ROT IMoniker* CurrentMoniker; while (!bSuccess && MonikersTable->Next(1, &CurrentMoniker, NULL) == S_OK) { IBindCtx* BindContext; LPOLESTR OutName; CComPtr<IUnknown> ComObject; if (SUCCEEDED(CreateBindCtx(0, &BindContext)) && SUCCEEDED(CurrentMoniker->GetDisplayName(BindContext, NULL, &OutName)) && IsVisualStudioMoniker(FString(OutName), InLocations) && SUCCEEDED(RunningObjectTable->GetObject(CurrentMoniker, &ComObject))) { CComPtr<EnvDTE::_DTE> TempDTE; TempDTE = ComObject; // Get the solution path for this instance // If it equals the solution we would have opened above in RunVisualStudio(), we'll take that CComPtr<EnvDTE::_Solution> Solution; LPOLESTR OutPath; if (SUCCEEDED(TempDTE->get_Solution(&Solution)) && SUCCEEDED(Solution->get_FullName(&OutPath))) { FString Filename(OutPath); FPaths::NormalizeFilename(Filename); if( Filename == InSolutionPath ) { OutDTE = TempDTE; bSuccess = true; } } } BindContext->Release(); CurrentMoniker->Release(); } MonikersTable->Release(); RunningObjectTable->Release(); } return bSuccess; }
IFileIsInUse* CreateIFileIsInUse(const string& File) { IFileIsInUse *pfiu = nullptr; IRunningObjectTable *prot; if (SUCCEEDED(GetRunningObjectTable(0, &prot))) { IMoniker *pmkFile; if (SUCCEEDED(CreateFileMoniker(File.data(), &pmkFile))) { IEnumMoniker *penumMk; if (SUCCEEDED(prot->EnumRunning(&penumMk))) { HRESULT hr = E_FAIL; ULONG celt; IMoniker *pmk; while (FAILED(hr) && (penumMk->Next(1, &pmk, &celt) == S_OK)) { DWORD dwType; if (SUCCEEDED(pmk->IsSystemMoniker(&dwType)) && dwType == MKSYS_FILEMONIKER) { IMoniker *pmkPrefix; if (SUCCEEDED(pmkFile->CommonPrefixWith(pmk, &pmkPrefix))) { if (pmkFile->IsEqual(pmkPrefix) == S_OK) { IUnknown *punk; if (prot->GetObject(pmk, &punk) == S_OK) { hr = punk->QueryInterface( #ifdef __GNUC__ IID_IFileIsInUse, IID_PPV_ARGS_Helper(&pfiu) #else IID_PPV_ARGS(&pfiu) #endif ); punk->Release(); } } pmkPrefix->Release(); } } pmk->Release(); } penumMk->Release(); } pmkFile->Release(); } prot->Release(); } return pfiu; }
JNIEXPORT jlong JNICALL Java_com4j_Native_getNextRunningObject(JNIEnv *env, jclass __unused__, jlong rotPointer, jlong enumMonikerPointer){ IRunningObjectTable *rot = reinterpret_cast<IRunningObjectTable*>(rotPointer); IEnumMoniker *enumMoniker = reinterpret_cast<IEnumMoniker*>(enumMonikerPointer); IMoniker *moniker; HRESULT hr = enumMoniker->Next(1, &moniker, NULL); if(hr == S_FALSE) { // This value indicates that there are no more elements, so do not report an error but return 0; // The Java part is responsible to call the Release on the rot and enumMoniker pointers! return 0; } else if(hr != S_OK){ error(env, __FILE__, __LINE__, hr, "IEnumMoniker:Next failed"); return 0; } IUnknown *unknown; rot->GetObject(moniker, &unknown); return reinterpret_cast<jlong>(unknown); }
/** Accesses the correct visual studio instance if possible. */ EAccessVisualStudioResult AccessVisualStudioViaDTE(TComPtr<EnvDTE::_DTE>& OutDTE, const FString& InSolutionPath, const TArray<FVisualStudioSourceCodeAccessor::VisualStudioLocation>& InLocations) { EAccessVisualStudioResult AccessResult = EAccessVisualStudioResult::VSInstanceIsNotOpen; // Open the Running Object Table (ROT) IRunningObjectTable* RunningObjectTable; if(SUCCEEDED(GetRunningObjectTable(0, &RunningObjectTable)) && RunningObjectTable) { IEnumMoniker* MonikersTable; if(SUCCEEDED(RunningObjectTable->EnumRunning(&MonikersTable))) { MonikersTable->Reset(); // Look for all visual studio instances in the ROT IMoniker* CurrentMoniker; while(AccessResult != EAccessVisualStudioResult::VSInstanceIsOpen && MonikersTable->Next(1, &CurrentMoniker, NULL) == S_OK) { IBindCtx* BindContext; LPOLESTR OutName; if(SUCCEEDED(CreateBindCtx(0, &BindContext)) && SUCCEEDED(CurrentMoniker->GetDisplayName(BindContext, NULL, &OutName))) { if(IsVisualStudioDTEMoniker(FString(OutName), InLocations)) { TComPtr<IUnknown> ComObject; if(SUCCEEDED(RunningObjectTable->GetObject(CurrentMoniker, &ComObject))) { TComPtr<EnvDTE::_DTE> TempDTE; if (SUCCEEDED(TempDTE.FromQueryInterface(__uuidof(EnvDTE::_DTE), ComObject))) { // Get the solution path for this instance // If it equals the solution we would have opened above in RunVisualStudio(), we'll take that TComPtr<EnvDTE::_Solution> Solution; BSTR OutPath = nullptr; if (SUCCEEDED(TempDTE->get_Solution(&Solution)) && SUCCEEDED(Solution->get_FullName(&OutPath))) { FString Filename(OutPath); FPaths::NormalizeFilename(Filename); if (Filename == InSolutionPath) { OutDTE = TempDTE; AccessResult = EAccessVisualStudioResult::VSInstanceIsOpen; } SysFreeString(OutPath); } else { UE_LOG(LogVSAccessor, Warning, TEXT("Visual Studio is open but could not be queried - it may be blocked by a modal operation")); AccessResult = EAccessVisualStudioResult::VSInstanceIsBlocked; } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Could not get DTE interface from returned Visual Studio instance")); AccessResult = EAccessVisualStudioResult::VSInstanceIsBlocked; } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't get Visual Studio COM object")); AccessResult = EAccessVisualStudioResult::VSInstanceUnknown; } } } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't get display name")); AccessResult = EAccessVisualStudioResult::VSInstanceUnknown; } BindContext->Release(); CurrentMoniker->Release(); } MonikersTable->Release(); } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't enumerate ROT table")); AccessResult = EAccessVisualStudioResult::VSInstanceUnknown; } RunningObjectTable->Release(); } else { UE_LOG(LogVSAccessor, Warning, TEXT("Couldn't get ROT table")); AccessResult = EAccessVisualStudioResult::VSInstanceUnknown; } return AccessResult; }