IDebugProgramProvider2::WatchForProviderEvents
如需 Visual Studio 2017 的最新文件請參閱 Visual Studio 2017 文件。
允許的連接埠事件通知的程序。
語法
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列舉型別。 下列旗標是此呼叫的典型︰
旗標 | 說明 |
---|---|
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
旗標。
範例
下列範例示範如何實作這個方法的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