私はこれを自分で考え出しました。 RunningObjectTableは、すべてのVSインスタンスを反復処理し、私が期待しているソリューションを開いた状態で1つを探す方法です。
#define RETURN_ON_FAIL(expression) \
result = (expression); \
if (FAILED(result)) \
return false; \
else // To prevent danging else condition
...
HRESULT result;
CLSID clsid;
CComPtr<IUnknown> punk;
CComPtr<EnvDTE::_DTE> dte;
RETURN_ON_FAIL(::CLSIDFromProgID(L"VisualStudio.DTE", &clsid));
...
// Search through the Running Object Table for an instance of Visual Studio
// to use that either has the correct solution already open or does not have
// any solution open.
CComPtr<IRunningObjectTable> ROT;
RETURN_ON_FAIL(GetRunningObjectTable(0, &ROT));
CComPtr<IBindCtx> bindCtx;
RETURN_ON_FAIL(CreateBindCtx(0, &bindCtx));
CComPtr<IEnumMoniker> enumMoniker;
RETURN_ON_FAIL(ROT->EnumRunning(&enumMoniker));
CComPtr<IMoniker> dteMoniker;
RETURN_ON_FAIL(CreateClassMoniker(clsid, &dteMoniker));
CComBSTR bstrSolution(solutionPath);
CComPtr<IMoniker> moniker;
ULONG monikersFetched = 0;
while (enumMoniker->Next(1, &moniker, &monikersFetched) == S_OK)
{
if (moniker->IsEqual(dteMoniker))
{
result = ROT->GetObject(moniker, &punk);
if (result == S_OK)
{
dte = punk;
if (dte)
{
CComPtr<EnvDTE::_Solution> solution;
RETURN_ON_FAIL(dte->get_Solution(&solution));
VARIANT_BOOL isOpen = FALSE;
RETURN_ON_FAIL(solution->get_IsOpen(&isOpen));
if (!isOpen)
{
RETURN_ON_FAIL(solution->Open(bstrSolution));
break;
}
else
{
CComBSTR fullName;
RETURN_ON_FAIL(solution->get_FullName(&fullName));
if (fullName == bstrSolution)
break;
}
}
}
punk = NULL;
}
moniker = NULL;
}
if (!dte)
{
RETURN_ON_FAIL(::CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, EnvDTE::IID__DTE, (LPVOID*)&punk));
dte = punk;
if (!dte)
return false;
if (solutionPath)
{
CComPtr<EnvDTE::_Solution> solution;
RETURN_ON_FAIL(dte->get_Solution(&solution));
CComBSTR bstrSolution(solutionPath);
RETURN_ON_FAIL(solution->Open(bstrSolution));
}
}
:私は、私が使用できるインスタンスが見つからない場合は、その後、私は新しいVS IDEを起動する)のCoCreateInstance(コール
EnvDTEをマクロまたはdllで使用していますか?場合によっては、代わりにShellExecuteやDDEを使用することも考えられます。 –
私はC++からネイティブで実行可能ファイルを使用しています。ソリューションが既に開いている可能性があるため、ShellExecuteを使用する必要はありません。私はすでにSolution.FullNameを見てこれを検出することができます。それが存在しない場合、私はVSを起動し、EnvDTEを介してそれを自動化しようとしています。 –
ahh - それはすでにVSの別のインスタンスに読み込まれている可能性があります。これがアドインまたはパッケージの場合は、別のインスタンスがすでにそのソリューションで実行されているかどうかを知るために、(他のインスタンスとともに)IPCを設定することができます。 –