141 lines
4.5 KiB
C#
141 lines
4.5 KiB
C#
|
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
|
|||
|
#region Using directives
|
|||
|
|
|||
|
using System;
|
|||
|
using System.Threading;
|
|||
|
using System.Reflection;
|
|||
|
using System.Runtime.InteropServices;
|
|||
|
using System.Diagnostics;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
namespace System.Workflow.Runtime.DebugEngine
|
|||
|
{
|
|||
|
[ComImport, Guid(Guids.CLSID_WDEProgramPublisher)]
|
|||
|
internal class WDEProgramPublisher
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
internal sealed class ProgramPublisher
|
|||
|
{
|
|||
|
#region Data members
|
|||
|
|
|||
|
private bool isPublished = false;
|
|||
|
IWDEProgramPublisher publisher;
|
|||
|
private DebugController controller;
|
|||
|
GCHandle gchWdeProgramNode; // This is used to pin the wdeProgramNodeSingleton (VS Debugger is using address to calculate cookies)
|
|||
|
private IWDEProgramNode wdeProgramNodeSingleton;
|
|||
|
|
|||
|
#endregion
|
|||
|
|
|||
|
#region Methods
|
|||
|
|
|||
|
public ProgramPublisher()
|
|||
|
{
|
|||
|
this.publisher = null;
|
|||
|
}
|
|||
|
|
|||
|
public bool Publish(DebugController controller)
|
|||
|
{
|
|||
|
Debug.WriteLine("WDE: ProgramPublisher.Publish()");
|
|||
|
|
|||
|
// In order to guarantee that the Program Nodes are always in the MTA, publish on a separate thread.
|
|||
|
if (isPublished)
|
|||
|
return false;
|
|||
|
|
|||
|
try
|
|||
|
{
|
|||
|
this.controller = controller;
|
|||
|
Thread publisherThread = new Thread(PublisherThreadFunc);
|
|||
|
publisherThread.SetApartmentState(ApartmentState.MTA);
|
|||
|
publisherThread.IsBackground = true;
|
|||
|
publisherThread.Start();
|
|||
|
publisherThread.Join();
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
// Eat up exceptions if the debugger is not installed.
|
|||
|
Debug.WriteLine("WDE: ProgramPublisher.Publish() exception: " + e.ToString());
|
|||
|
}
|
|||
|
|
|||
|
return this.isPublished;
|
|||
|
}
|
|||
|
|
|||
|
private void PublisherThreadFunc()
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
this.publisher = new WDEProgramPublisher() as IWDEProgramPublisher;
|
|||
|
this.wdeProgramNodeSingleton = new ProgramNode(this.controller);
|
|||
|
this.gchWdeProgramNode = GCHandle.Alloc(this.wdeProgramNodeSingleton);
|
|||
|
|
|||
|
this.publisher.Publish(this.wdeProgramNodeSingleton);
|
|||
|
this.isPublished = true;
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
// Ignore any exceptions that are caused by WDE.dll not being present or registered.
|
|||
|
Debug.WriteLine("WDE: ProgramPublisher.PublisherThreadFunc() exception: " + e.ToString());
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
public void Unpublish()
|
|||
|
{
|
|||
|
if (!isPublished)
|
|||
|
return;
|
|||
|
|
|||
|
Debug.WriteLine("WDE: ProgramPublisher.Unpublish()");
|
|||
|
|
|||
|
// In order to guarantee that the Program Nodes are always in the MTA, unpublish on a separate thread.
|
|||
|
try
|
|||
|
{
|
|||
|
Thread unpublisherThread = new Thread(UnpublishThreadFunc);
|
|||
|
unpublisherThread.SetApartmentState(ApartmentState.MTA);
|
|||
|
unpublisherThread.IsBackground = true;
|
|||
|
unpublisherThread.Start();
|
|||
|
unpublisherThread.Join();
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
// Eat up exceptions if the debugger is not installed, etc.
|
|||
|
Debug.WriteLine("WDE: ProgramPublisher.Unpublish() exception: " + e.ToString());
|
|||
|
}
|
|||
|
|
|||
|
Debug.WriteLine("WDE: ProgramPublisher.Unpublish() Done");
|
|||
|
}
|
|||
|
|
|||
|
private void UnpublishThreadFunc()
|
|||
|
{
|
|||
|
try
|
|||
|
{
|
|||
|
this.publisher.Unpublish(this.wdeProgramNodeSingleton);
|
|||
|
}
|
|||
|
catch (Exception e)
|
|||
|
{
|
|||
|
Debug.WriteLine("WDE: ProgramPublisher.UnpublishThreadFunc(): catch exception " + e.ToString());
|
|||
|
// We eat up any exceptions that can occur because the host process is abnormally terminated.
|
|||
|
}
|
|||
|
finally
|
|||
|
{
|
|||
|
this.gchWdeProgramNode.Free(); // Rrelease pin on the this.wdeProgramNodeSingleton
|
|||
|
|
|||
|
Marshal.ReleaseComObject(this.publisher);
|
|||
|
this.publisher = null;
|
|||
|
}
|
|||
|
|
|||
|
this.isPublished = false;
|
|||
|
}
|
|||
|
|
|||
|
#endregion
|
|||
|
}
|
|||
|
|
|||
|
[ComImport(), Guid(Guids.IID_IWDEProgramPublisher), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
|
|||
|
internal interface IWDEProgramPublisher
|
|||
|
{
|
|||
|
void Publish([MarshalAs(UnmanagedType.IUnknown)] object ProgramNode);
|
|||
|
void Unpublish([MarshalAs(UnmanagedType.IUnknown)] object ProgramNode);
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
}
|