IDebugProgramProvider2::WatchForProviderEvents
Ermöglicht es dem Prozess, über Portereignisse benachrichtigt zu werden.
Syntax
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-Aufzählung . Die folgenden Flags sind typisch für diesen Aufruf:
Flag | Beschreibung |
---|---|
PFLAG_REMOTE_PORT |
Der Anrufer wird auf einem Remotecomputer ausgeführt. |
PFLAG_DEBUGGEE |
Der Aufrufer wird derzeit gedebuggt (zusätzliche Informationen zum Marshalling werden für jeden Knoten zurückgegeben). |
PFLAG_ATTACHED_TO_DEBUGGEE |
Der Aufrufer wurde angefügt, aber nicht vom Debugger gestartet. |
PFLAG_REASON_WATCH |
Der Anrufer möchte auf Ereignisse achten. Wenn dieses Kennzeichen nicht festgelegt ist. anschließend wird das Rückrufereignis entfernt, und der Anrufer empfängt keine Benachrichtigungen mehr. |
pPort
[in] Der Port, auf dem der Aufrufvorgang 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 von Debugmodulen, die dem Prozess zugeordnet sind.
guidLaunchingEngine
[in] GUID des Debugmoduls, das diesen Prozess gestartet hat (falls vorhanden).
pEventCallback
[in] Ein IDebugPortNotify2-Objekt , das die Ereignisbenachrichtigungen empfängt.
Rückgabewert
Wenn die Ausführung erfolgreich ist, wird S_OK
, andernfalls ein Fehlercode zurückgegeben.
Hinweise
Wenn ein Aufrufer einen Ereignishandler entfernen möchte, der mit einem vorherigen Aufruf dieser Methode eingerichtet wurde, übergibt der Aufrufer dieselben Parameter wie beim ersten Mal, verlässt aber die PFLAG_REASON_WATCH
Kennzeichnung.
Beispiel
Das folgende Beispiel zeigt, wie Sie diese Methode für ein CDebugEngine-Objekt implementieren, 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 received 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;
}