#define _WIN32_DCOM
#include <windows.h>
#include <corhdr.h>
#include <cordebug.h>
#pragma comment(lib, "CorGuids.lib")
#include <MSCorEE.h>
#pragma comment(lib, "MSCorEE.lib")
#include <iostream>
#include "CorDbgManagedCallback.h"
int _tmain(int argc, _TCHAR* argv[])
{
HRESULT hr = E_FAIL;
ICorDebug * debug = NULL;
ICorDebugProcess* process = NULL;
//////////////////////////////////////////////////////////////////////////
hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); // MTA is a must.
if (FAILED(hr))
goto cleanup;
const wchar_t * szDebuggeeVersion2 = L"v2.0.50727"; // if we’re debugging a v2.0 debuggee.
const int iDebuggerVersion = CorDebugVersion_2_0; // if we’re a v2.0 debugger.
// ICorDebug 2.0 requires creating COM object with this method,
// instead of CoCreateInstance. Versioning issue is resolved here.
hr = CreateDebuggingInterfaceFromVersion(
CorDebugVersion_2_0, szDebuggeeVersion2, (IUnknown**) &debug);
if (FAILED(hr))
goto cleanup;
//////////////////////////////////////////////////////////////////////////
hr = debug->Initialize();
if (FAILED(hr))
goto cleanup;
// Receiving managed debugging event.
hr = debug->SetManagedHandler(&g_corDbgManagedCallback);
if (FAILED(hr))
goto cleanup;
// Not implementing in this sample code.
//hr = debug->SetUnmanagedHandler(); // for interop debugging…
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
// Prepare event object to sync debugging event.
g_event = CreateEvent(NULL, TRUE, FALSE, EVENT_OBJECT);
if (g_event == NULL)
goto cleanup;
// second param of CreateProcess must not be a const string.
wchar_t buffer[MAX_PATH] = { 0 };
hr = debug->CreateProcess(
L"debuggee.exe", // Specify executable image of debuggee.
buffer,
NULL,
NULL,
FALSE,
CREATE_NEW_CONSOLE,
NULL,
NULL,
&si,
&pi,
DEBUG_NO_SPECIAL_OPTIONS,
&process
);
if (FAILED(hr))
goto cleanup;
// We still need to close this two handles, since they are useless
// to debugger!!!
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
while (true)
{
// Resume after ICorDebugManagedCallback::ExitProcess event.
WaitForSingleObject(g_event, INFINITE);
break;
}
// Terminate should not be called until an
// ICorDebugManagedCallback::ExitProcess callback has been
// received for all processes being debugged.
hr = debug->Terminate();
if (FAILED(hr))
goto cleanup;
//////////////////////////////////////////////////////////////////////////
cleanup:
if (process != NULL)
process->Release();
if (debug != NULL)
debug->Release();
if (g_event != NULL)
CloseHandle(g_event);
CoUninitialize();
return 0;
}
Austin.D @ Autodesk