public ClrRuntime Attach(Process process, int attachWaitTimeMilliseconds)
{
if(this.currentProcess != null)
{
throw new InvalidOperationException(string.Format("Already attached to process {0}:{1}, use Detach() first.", this.currentProcess.ProcessName, this.currentProcess.Id));
}
DataTarget dataTarget = DataTarget.AttachToProcess(process.Id, (uint)attachWaitTimeMilliseconds);
// Make sure the CLR is even found
if(dataTarget.ClrVersions.Count == 0)
{
throw new InvalidOperationException(string.Format("The specified process {0}:{1} does not appear to have the CLR loaded in it.", process.ProcessName, process.Id));
}
else if(dataTarget.ClrVersions.Count > 1)
{
// REVISIT: what happens if there's multiple ClrVersions?
}
ClrInfo clrInfo = dataTarget.ClrVersions[0];
string dacLocation = clrInfo.TryGetDacLocation();
// Make sure we found the DAC location, otherwise we can't create the runtime
if(string.IsNullOrEmpty(dacLocation))
{
throw new InvalidOperationException(string.Format("Unable to locate the DAC for the target version of the CLR runtime ({0}) for process {1}:{2}.", clrInfo.Version, process.ProcessName, process.Id));
}
// Make sure that if we're unloaded we don't kill off the process
dataTarget.DebuggerInterface.SetProcessOptions(DEBUG_PROCESS.DETACH_ON_EXIT);
this.currentClrRuntime = dataTarget.CreateRuntime(dacLocation);
this.currentDataTarget = dataTarget;
this.currentProcess = process;
this.outputWriter.WriteLine("Successfully attached to {0}:{1}...", process.ProcessName, process.Id);
this.outputWriter.WriteLine("CLR Version: {0}", clrInfo.Version);
return this.currentClrRuntime;
}