2009-05-18 30 views
0

私はEnvDTE COMオブジェクトを使用してVisual Studioを自動化しています。私はまだドキュメンテーションを見ていますが、私はここで質問をドロップして、誰かがこれを行う方法をすでに知っているかどうかを確かめました。EnvDTEを使用して新しいビジュアルスタジオインスタンスを開くにはどうすればよいですか?

問題は、DTEオブジェクトを取得して、ソリューションが開いているかどうかを調べるときに、解決策が期待どおりでない場合はVisual Studioの別のインスタンスを開く必要があるということです。 VSの既存のインスタンスに対して別のソリューションをロードする必要はありません。

+0

EnvDTEをマクロまたはdllで使用していますか?場合によっては、代わりにShellExecuteやDDEを使用することも考えられます。 –

+0

私はC++からネイティブで実行可能ファイルを使用しています。ソリューションが既に開いている可能性があるため、ShellExecuteを使用する必要はありません。私はすでにSolution.FullNameを見てこれを検出することができます。それが存在しない場合、私はVSを起動し、EnvDTEを介してそれを自動化しようとしています。 –

+0

ahh - それはすでにVSの別のインスタンスに読み込まれている可能性があります。これがアドインまたはパッケージの場合は、別のインスタンスがすでにそのソリューションで実行されているかどうかを知るために、(他のインスタンスとともに)IPCを設定することができます。 –

答えて

2

私はこれを自分で考え出しました。 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(コール
関連する問題