Freigeben über


IDebugProgramProvider2::WatchForProviderEvents

Ermöglicht den von den Anschluss Prozess Ereignissen benachrichtigt zu werden.

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
);

Parameter

  • Flags
    [in] Eine Kombination von Flags aus der PROVIDER_FLAGS-Enumeration. Die folgenden Flags sind für diesen Aufruf typisch:

    Flag

    Beschreibung

    PFLAG_REMOTE_PORT

    Aufrufer auf dem Remotecomputer ausgeführt wird.

    PFLAG_DEBUGGEE

    Aufrufer zur Zeit gedebuggt wird (weitere Informationen über Marshalling wird für jeden Knoten zurückgegeben).

    PFLAG_ATTACHED_TO_DEBUGGEE

    Aufrufer angefügt wurde, aber nicht vom Debugger gestartet.

    PFLAG_REASON_WATCH

    Aufrufer für Ereignisse überwachen möchte. Wenn dieses Flag nicht festgelegt ist. Anschließend wird das Rückrufereignis entfernt, und der Aufrufer empfängt keine Benachrichtigungen mehr.

  • pPort
    [in] Der Port, den der aufrufende Prozess ausgeführt wird.

  • processId
    [in] Eine AD_PROCESS_ID Struktur, die die ID des Prozesses enthält, der das betreffende Programm enthält.

  • EngineFilter
    [in] Ein Array von GUIDs Debuggen von den Modulen, die dem Prozess.

  • guidLaunchingEngine
    [in] GUID des Debugmoduls, das dieser Vorgang ausgelöst hat (sofern vorhanden).

  • pEventCallback
    [in] Ein IDebugPortNotify2-Objekt, das die Ereignisbenachrichtigungen empfängt.

Rückgabewert

Bei Erfolg gibt S_OKzurück. andernfalls gibt einen Fehlercode zurück.

Hinweise

Wenn ein Aufrufer einen Ereignishandler entfernt werden soll, der mit einem vorherigen Aufruf dieser Methode erstellt wurde, wird der Aufrufer die gleichen Parameter, die sie das erste Mal tat, aber bewirkt, dass vom PFLAG_REASON_WATCH-Flag.

Beispiel

Im folgenden Beispiel wird veranschaulicht, wie diese Methode für ein CDebugEngine-Objekt implementiert, das die IDebugProgramProvider2-Schnittstelle verfügbar macht.

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;
}

Siehe auch

Referenz

IDebugProgramProvider2

PROVIDER_FLAGS

AD_PROCESS_ID

CONST_GUID_ARRAY

IDebugDefaultPort2

IDebugPortNotify2