Поделиться через


IDebugProgramProvider2::WatchForProviderEvents

Разрешает процесса для уведомления событий порта.

HRESULT WatchForProviderEvents(
   PROVIDER_FLAGS       Flags,
   IDebugDefaultPort2*  pPort,
   AD_PROCESS_ID        processId,
   CONST_GUID_ARRAY     EngineFilter,
   REFGUID              guidLaunchingEngine,
   IDebugPortNotify2*   pEventCallback
);
int WatchForProviderEvents(
   enum_PROVIDER_FLAGS   Flags,
   IDebugDefaultPort2    pPort,
   AD_PROCESS_ID         ProcessId,
   CONST_GUID_ARRAY      EngineFilter,
   ref Guid              guidLaunchingEngine,
   IDebugPortNotify2     pEventCallback
);

Параметры

  • Flags
    [in] сочетание пометит из PROVIDER_FLAGS перечисление. Следующие флаги типичны для данного вызова.

    Flag

    Описание

    PFLAG_REMOTE_PORT

    Вызывающий код выполняется на удаленном компьютере.

    PFLAG_DEBUGGEE

    Вызывающий объект в настоящее время отладки (дополнительные сведения о выстраивать возвращается для каждого узла).

    PFLAG_ATTACHED_TO_DEBUGGEE

    Вызывающий объект был вложен в но не был запущен отладчиком.

    PFLAG_REASON_WATCH

    Вызывающий объект должен контрольных событий. Если этот пометить не задан. затем событие обратного вызова удалено и вызывающий объект больше не получает уведомления.

  • pPort
    [in] порт вызывающий процесс запущен.

  • processId
    [in] AD_PROCESS_ID структура, содержащая идентификатор процесса, содержащего программу в вопросе.

  • EngineFilter
    [in] массив идентификаторов GUID обработчиков отладки, связанных с процессом.

  • guidLaunchingEngine
    [in] идентификатор GUID обработчика отладки, запустившего этот процесс (если есть).

  • pEventCallback
    [in] IDebugPortNotify2 объект, который получает уведомления о событиях.

Возвращаемое значение

В случае успеха возвращает S_OK; в противном случае возвращает код ошибки.

Заметки

Если вызывающий объект является необходимость удаления обработчика событий, который был установлен с предыдущим вызовом этого метода, вызывающий объект проходит те же параметры, что он внесены в первый раз, но оставляет с PFLAG_REASON_WATCH пометить.

Пример

В следующем примере показано, как реализовать этот метод, a CDebugEngine объект, предоставляющий IDebugProgramProvider2 интерфейс.

STDMETHODIMP CDebugEngine::WatchForProviderEvents(
    PROVIDER_FLAGS Flags, 
    IDebugDefaultPort2 *pPort, 
    AD_PROCESS_ID processId, 
    CONST_GUID_ARRAY EngineFilter, 
    REFGUID guidLaunchingEngine, 
    IDebugPortNotify2 *pPortNotify)
{
    HRESULT hRes = E_FAIL;

    if (EVAL(pPort != NULL) && EVAL(pPortNotify != NULL))
    {
        // We will only watch/send events about the process if the debugger
        // is actually debugging the process, and only if this is an attach or a LoRIE launch
        if (IsFlagSet(Flags, PFLAG_DEBUGGEE) &&
            guidLaunchingEngine == GUID_NULL &&
            processId.ProcessIdType == AD_PROCESS_ID_SYSTEM)
        {
            // We don't support WatchForProviderEvents when in interop mode
            if (m_fInterop)
            {
                ASSERT(!"Shouldn't ever be called in interop mode");
                hRes = E_FAIL;
            }
            else
            {
                if (IsFlagSet(Flags, PFLAG_REASON_WATCH))
                {
                    // QI to get IDebugEventCallback2 which is required.
                    CComQIPtr<IDebugEventCallback2> pCallback(pPortNotify);

                    ASSERT(pCallback != NULL);
                    if ( pCallback != NULL )
                    {
                        // Register the callback
                        hRes = this->InitDebugSession(pCallback);

                        if ( S_OK == hRes )
                        {
                            // Get the IDebugProcess2 from the port and call AttachImpl
                            CComPtr<IDebugProcess2> spProcess;

                            hRes = pPort->GetProcess(processId, &spProcess);

                            if (HREVAL(S_OK, hRes))
                            {
                                hRes = AttachImpl(spProcess, NULL, NULL, processId.ProcessId.dwProcessId, ATTACH_REASON_USER, NULL);

                                if ( FAILED(hRes) && (!m_pPidList || 0 == m_pPidList->GetCount()) )
                                    this->Cleanup();
                            }
                        }
                        else
                            this->Cleanup();
                    }
                    else
                        hRes = E_FAIL;
                }
                else
                {
                    // Detach will be done by SDM calling on programs directly if there are managed programs.

                    // This handling is the case where no managed code ever ran.
                    if ( this->IsProcessBeingDebugged(processId.ProcessId.dwProcessId) )
                    {
                        ProgramList *pProgList = this->GetProgramListCopy();

                        if ( EVAL(pProgList) )
                        {
                            if ( pProgList->GetCount() == 0)
                            {
                                CComPtr<ICorDebugProcess> pCorProcess;

                                hRes = this->GetCorProcess(processId.ProcessId.dwProcessId, &pCorProcess);

                                if (HREVAL(S_OK, hRes) )
                                {
                                    hRes = pCorProcess->Stop(INFINITE);

                                    if ( HREVAL(S_OK, hRes) )
                                        hRes = pCorProcess->Detach();
                                }

                                // Tell the engine that it should unregister this process from com+
                                this->UnregisterProcess(processId.ProcessId.dwProcessId);

                                // If there are no more pids left then cleanup everything.
                                if ( 0 == m_pPidList->GetCount() )
                                    this->Cleanup();
                            }
                            // This is needed for cases where the SDM has not yet recieved program create
                            // by the time that we need to detach (example: the managed attach succeeds,
                            // but some other attach step fails).
                            else
                            {
                                PROGNODE *pProgNode = NULL;
                                while ( pProgNode = pProgList->Next(pProgNode) )
                                {
                                    CDebugProgram * pProgram = ((CDebugProgram *)pProgNode->data);
                                    hRes = pProgram->Detach();
                                }
                            }

                            delete pProgList;
                        }
                    }
                    else
                        hRes = S_OK;
                }
            }
        }
        else
        {
            hRes = S_FALSE;
        }
    }
    else
    {
        hRes = E_INVALIDARG;
    }

    return hRes;
}

См. также

Ссылки

IDebugProgramProvider2

PROVIDER_FLAGS

AD_PROCESS_ID

CONST_GUID_ARRAY

IDebugDefaultPort2

IDebugPortNotify2