Как открыть новый экземпляр Visual Studio с помощью EnvDTE? - PullRequest
0 голосов
/ 19 мая 2009

Я использую COM-объекты EnvDTE для автоматизации Visual Studio. Я все еще просматриваю документацию, но я решил оставить здесь вопрос, чтобы узнать, знает ли кто-нибудь, как это сделать.

Итак, проблема в том, что когда я получаю объект DTE и смотрю, какое решение открыто, мне нужно открыть другой экземпляр Visual Studio, если решение не является тем, которое я ожидаю. Я не обязательно хочу загружать другое решение поверх существующего экземпляра VS.

1 Ответ

2 голосов
/ 19 мая 2009

Итак, я понял это самостоятельно. Оказывается, что 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 ) );
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...