2009-05-18 32 views
0

我使用EnvDTE COM對象自動化的Visual Studio。我仍在瀏覽文檔,但是,我想我會在這裏放下問題,看看是否有人已經知道如何做到這一點。如何使用EnvDTE打開新的Visual Studio實例?

所以,問題是,當我得到的DTE對象,看看有什麼解決辦法是開放的,我需要的,如果該解決方案是不是一個我期待打開Visual Studio中的另一個實例。我不一定要通過現有的VS實例加載另一個解決方案。

+0

你在宏或在DLL中使用EnvDTE?根據具體情況,可能會考慮使用ShellExecute甚至DDE。 – 2009-05-18 21:16:31

+0

我在C++中以可執行文件的形式使用它。我不需要使用ShellExecute,因爲解決方案可能已經打開。我可以通過查看Solution.FullName來檢測到這一點。在不存在的情況下,我期望啓動VS並通過EnvDTE繼續自動化它。 – 2009-05-18 21:52:59

+0

啊 - 我看到了 - 它可能已經加載到VS的另一個實例中。如果這是一個插件或一個包,你可以設置一些IPC(與其他實例),讓你知道,如果另一個實例已經在它的解決方案上運行。 – 2009-05-18 22:30:43

回答

2

所以,我想通了這一點我自己。事實證明,在RunningObjectTable是遍歷所有VS情況下,尋找一個與解決方案開放,我希望的方式。如果我沒有找到,我可以用一個實例,然後我調用CoCreateInstance()合作推出一個新的VS IDE:

#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)); 
    } 
} 
相關問題