Imported Upstream version 4.6.0.125

Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2016-08-03 10:59:49 +00:00
parent a569aebcfd
commit e79aa3c0ed
17047 changed files with 3137615 additions and 392334 deletions

View File

@@ -0,0 +1,22 @@
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
#region Using directives
using System;
using System.Runtime.InteropServices;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
#endregion
namespace System.Workflow.Runtime.DebugEngine
{
[Serializable]
[StructLayout(LayoutKind.Sequential)]
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public struct ActivityHandlerDescriptor
{
[MarshalAs(UnmanagedType.BStr)]
public string Name;
public int Token;
}
}

View File

@@ -0,0 +1,133 @@
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
#region Using directives
using System;
using System.Threading;
#endregion
namespace System.Workflow.Runtime.DebugEngine
{
//
// IMPORTANT: Do not edit this file without consulting Break Safe Synchronization.doc!
//
internal abstract class BreakSafeBase<T> where T : ICloneable, new()
{
#region Data members
private volatile object currentData; // object because type parameters instances cannot be volatile.
private T nonEEDataClone;
private volatile bool nonEEDataConsistent;
private volatile bool nonEEIgnoreUpdate;
private Mutex nonEELock;
private object controllerUpdateObject;
private int controllerManagedThreadId;
#endregion
#region Methods and properties
protected BreakSafeBase(int controllerManagedThreadId)
{
this.currentData = new T();
this.nonEEDataClone = default(T);
this.nonEEDataConsistent = false;
this.nonEEIgnoreUpdate = false;
this.nonEELock = new Mutex(false);
this.controllerManagedThreadId = controllerManagedThreadId;
}
private bool IsEECall
{
get
{
return Thread.CurrentThread.ManagedThreadId == this.controllerManagedThreadId;
}
}
protected object GetControllerUpdateObject()
{
return this.controllerUpdateObject;
}
protected void SetControllerUpdateObject(object updateObject)
{
// Ensure that the access to the variable this.controllerUpdateObject is exactly one instruction - StFld in this case.
this.controllerUpdateObject = updateObject;
}
protected T GetReaderData()
{
// Ensure that the access to the variable this.currentData is exactly one instruction - LdFld in this case.
object data = this.currentData;
return (T)data;
}
protected T GetWriterData()
{
if (IsEECall)
{
if (this.nonEEDataConsistent && this.nonEEIgnoreUpdate == false)
{
// Modify the object referred to by this.currentData directly.
return (T)this.currentData;
}
else
{
// Clone and discard any non-EE update.
this.nonEEIgnoreUpdate = true;
return (T)((T)this.currentData).Clone();
}
}
else
{
// Reset the flag so that we can keep track of any concurrent EE updates.
this.nonEEIgnoreUpdate = false;
// Ensure that the access to the variable this.currentData is exactly one instruction - LdFld in this case.
object data = this.currentData;
return (T)((T)data).Clone();
}
}
protected void SaveData(T data)
{
if (IsEECall)
this.currentData = data;
else
{
// The non-EE clone is now in a consistent state.
this.nonEEDataClone = data;
this.nonEEDataConsistent = true;
this.controllerUpdateObject = null;
// If an EE call has already modified the data, it would have also performed current non-EE update
// when the debugger entered break mode. So discard the update. Asl ensure that the access to the
// variable this.currentData is exactly one instruction - StFld in this case.
if (this.nonEEIgnoreUpdate == false)
this.currentData = data;
// Clear the flag because we will clear the this.nonEEDataClone.
this.nonEEDataConsistent = false;
this.nonEEDataClone = default(T);
}
}
protected void Lock()
{
// Serialize non-EE calls and do not invoke synchronization primitives during FuncEval.
if (!IsEECall)
this.nonEELock.WaitOne();
}
protected void Unlock()
{
// Serialize non-EE calls and do not invoke synchronization primitives during FuncEval.
if (!IsEECall)
this.nonEELock.ReleaseMutex();
}
#endregion
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,209 @@
#region Using directives
using System;
using System.Threading;
using System.Reflection;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Globalization;
using Microsoft.Win32;
#endregion
namespace System.Workflow.Runtime.DebugEngine
{
internal sealed class DebugControllerThread
{
#region Data members
private Thread controllerThread = null;
private int threadId = 0;
private ManualResetEvent threadInitializedEvent = null;
private volatile bool runThread = false;
private static readonly string ExpressionEvaluationFrameTypeName = "ExpressionEvaluationFrameTypeName";
#endregion
#region Methods
public DebugControllerThread()
{
this.threadInitializedEvent = new ManualResetEvent(false);
this.threadInitializedEvent.Reset();
this.controllerThread = new Thread(ControllerThreadFunction);
this.controllerThread.IsBackground = true;
this.controllerThread.Priority = ThreadPriority.Lowest;
this.controllerThread.Name = "__dct__";
}
public void RunThread(IInstanceTable instanceTable)
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.DebugControllerThread():"));
if (this.controllerThread == null)
return;
this.runThread = true;
this.controllerThread.Start(instanceTable);
this.threadInitializedEvent.WaitOne();
}
public void StopThread()
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.StopThread():"));
try
{
if (this.controllerThread != null)
{
this.runThread = false;
Thread.Sleep(10);
// On x64 we put the debug controller thread to Sleep(Timeout.Infinite) in
// ExpressionEvaluationFunction. This thread needs to be started before it
// a Join can execute.
if (this.controllerThread.IsAlive && IntPtr.Size == 8)
{
while (this.controllerThread.ThreadState == System.Threading.ThreadState.WaitSleepJoin)
{
this.controllerThread.Start();
this.controllerThread.Join();
}
}
else
this.controllerThread.Join();
}
}
catch (ThreadStateException)
{
// Ignore the ThreadStateException which will be thrown when StopThread() is called during
// AppDomain unload.
}
finally
{
this.controllerThread = null;
}
this.controllerThread = null;
this.threadId = 0;
this.threadInitializedEvent = null;
}
private void ControllerThreadFunction(object instanceTable)
{
try
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.ControllerThreadFunction():"));
IExpressionEvaluationFrame expressionEvaluationFrame = null;
try
{
RegistryKey debugEngineSubKey = Registry.LocalMachine.OpenSubKey(RegistryKeys.DebuggerSubKey);
if (debugEngineSubKey != null)
{
string evaluationFrameTypeName = debugEngineSubKey.GetValue(ExpressionEvaluationFrameTypeName, String.Empty) as string;
if (!String.IsNullOrEmpty(evaluationFrameTypeName) && Type.GetType(evaluationFrameTypeName) != null)
expressionEvaluationFrame = Activator.CreateInstance(Type.GetType(evaluationFrameTypeName)) as IExpressionEvaluationFrame;
}
}
catch { }
if (expressionEvaluationFrame == null)
{
Type eeFrameType = null;
const string eeFrameTypeNameFormat = "Microsoft.Workflow.DebugEngine.ExpressionEvaluationFrame, Microsoft.Workflow.ExpressionEvaluation, Version={0}.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35";
// Try versions 12.0.0.0, 11.0.0.0, 10.0.0.0
for (int version = 12; eeFrameType == null && version >= 10; --version)
{
try
{
eeFrameType = Type.GetType(string.Format(CultureInfo.InvariantCulture, eeFrameTypeNameFormat, version));
}
catch (TypeLoadException)
{
// Fall back to next-lower version
}
}
if (eeFrameType != null)
{
expressionEvaluationFrame = Activator.CreateInstance(eeFrameType) as IExpressionEvaluationFrame;
}
}
Debug.Assert(expressionEvaluationFrame != null, "Failed to create Expression Evaluation Frame.");
if (expressionEvaluationFrame != null)
expressionEvaluationFrame.CreateEvaluationFrame((IInstanceTable)instanceTable, (DebugEngineCallback)Delegate.CreateDelegate(typeof(DebugEngineCallback), this, "ExpressionEvaluationFunction"));
}
catch
{
// Don't throw exceptions to the Runtime, it would terminate the debugee.
}
}
// This thread spins forever. It is used by the Debug Engine to perform expression evaluation as a "carrier
// wave". It is created only when the debugger is attached and terminates itself when the debugger isn't
// attached anymore.
public void ExpressionEvaluationFunction()
{
this.threadId = NativeMethods.GetCurrentThreadId();
this.threadInitializedEvent.Set();
using (new DebuggerThreadMarker())
{
// If an exception occurs somehow, continue to spin.
while (this.runThread)
{
try
{
// Expression eval on x64 does not work (bug 18143) so
// don't let the thread spin.
if (IntPtr.Size == 8)
{
Thread.Sleep(Timeout.Infinite);
}
else
// Spin within the try catch.
while (this.runThread);
}
catch (ThreadAbortException)
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.ExpressionEvaluationFunction(): ThreadAbortException"));
// Explicitly do not call ResetAbort().
throw;
}
catch
{
Debug.WriteLine(string.Format(CultureInfo.CurrentCulture, "WDE: DebugControllerThread.ExpressionEvaluationFunction(): other exception"));
}
}
}
}
#endregion
#region Properties
public int ThreadId
{
get
{
return this.threadId;
}
}
public int ManagedThreadId
{
get
{
return this.controllerThread.ManagedThreadId;
}
}
#endregion
}
}

View File

@@ -0,0 +1,25 @@
#region Using directives
using System;
using System.Threading;
using System.Reflection;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Globalization;
using Microsoft.Win32;
#endregion
namespace System.Workflow.Runtime.DebugEngine
{
#region Interface IExpressionEvaluationFrame
public delegate void DebugEngineCallback();
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public interface IExpressionEvaluationFrame
{
void CreateEvaluationFrame(IInstanceTable instanceTable, DebugEngineCallback callback);
}
#endregion
}

View File

@@ -0,0 +1,165 @@
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
#region Using directives
using System;
using System.Workflow.Runtime;
using System.Collections.Generic;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
#endregion
namespace System.Workflow.Runtime.DebugEngine
{
//
// IMPORTANT: Do not edit this file without consulting Break Safe Synchronization.doc!
//
#region interface IInstanceTable
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public interface IInstanceTable
{
Activity GetActivity(string instanceId, string activityName);
}
#endregion
#region Class InstanceData
internal sealed class InstanceData : ICloneable
{
Activity rootActivity;
public Activity RootActivity
{
get
{
return this.rootActivity;
}
set
{
this.rootActivity = value;
}
}
public InstanceData(Activity rootActivity)
{
this.rootActivity = rootActivity;
}
object ICloneable.Clone()
{
InstanceData instanceData = new InstanceData(this.rootActivity);
return instanceData;
}
}
internal sealed class InstanceMap : Dictionary<Guid, InstanceData>, ICloneable
{
object ICloneable.Clone()
{
InstanceMap data = new InstanceMap();
foreach (Guid instsanceId in Keys)
data.Add(instsanceId, (InstanceData)(((ICloneable)(this[instsanceId])).Clone()));
return data;
}
}
#endregion
#region Class InstanceTable
internal sealed class InstanceTable : BreakSafeBase<InstanceMap>, IInstanceTable
{
public InstanceTable(int controllerManagedThreadId)
: base(controllerManagedThreadId)
{ }
// Controller invoked.
public void AddInstance(Guid instanceId, Activity rootActivity)
{
try
{
Lock();
InstanceMap instanceMap = GetWriterData();
instanceMap[instanceId] = new InstanceData(rootActivity);
SaveData(instanceMap);
}
finally
{
Unlock();
}
}
// Controller invoked.
public void RemoveInstance(Guid instanceId)
{
try
{
Lock();
InstanceMap instanceMap = GetWriterData();
instanceMap.Remove(instanceId);
SaveData(instanceMap);
}
finally
{
Unlock();
}
}
// Controller invoked during Dynamic Update notification subscription changes.
public Activity GetRootActivity(Guid instanceId)
{
try
{
Lock();
return GetReaderData()[instanceId].RootActivity;
}
finally
{
Unlock();
}
}
// Controller invoked during Dynamic Update notification subscription changes.
public void UpdateRootActivity(Guid instanceId, Activity rootActivity)
{
try
{
Lock();
InstanceMap instanceMap = GetWriterData();
instanceMap[instanceId].RootActivity = rootActivity;
SaveData(instanceMap);
}
finally
{
Unlock();
}
}
// DE invoked for watches through expression evaluation.
Activity IInstanceTable.GetActivity(string instanceId, string activityQualifiedName)
{
try
{
Lock();
Activity rootActivity = GetReaderData()[new Guid(instanceId)].RootActivity;
return DebuggerHelpers.ParseActivity(rootActivity, activityQualifiedName);
}
finally
{
Unlock();
}
}
}
#endregion
}

View File

@@ -0,0 +1,56 @@
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
#region Using directives
using System;
using System.IO;
using System.Xml;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Collections;
using System.Diagnostics;
using System.Runtime.Remoting;
using System.Collections.Generic;
using System.Runtime.Serialization;
using System.Workflow.Runtime;
using System.Workflow.Runtime.Hosting;
using System.Runtime.InteropServices;
using System.Runtime.Remoting.Channels;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel.Design;
using System.Workflow.ComponentModel.Serialization;
using System.Runtime.Serialization.Formatters;
using System.Configuration;
using System.Security.Permissions;
using System.Globalization;
using Microsoft.Win32;
using System.Security.AccessControl;
using System.Security.Principal;
#endregion
namespace System.Workflow.Runtime.DebugEngine
{
#region Interface IWorkflowDebugger
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public interface IWorkflowDebugger
{
void InstanceCreated(Guid programId, Guid instanceId, Guid scheduleTypeId);
void InstanceDynamicallyUpdated(Guid programId, Guid instanceId, Guid scheduleTypeId);
void InstanceCompleted(Guid programId, Guid instanceId);
void BeforeActivityStatusChanged(Guid programId, Guid scheduleTypeId, Guid instanceId, string activityQualifiedName, string hierarchicalActivityId, ActivityExecutionStatus status, int stateReaderId);
void ActivityStatusChanged(Guid programId, Guid scheduleTypeId, Guid instanceId, string activityQualifiedName, string hierarchicalActivityId, ActivityExecutionStatus status, int stateReaderId);
void SetInitialActivityStatus(Guid programId, Guid scheduleTypeId, Guid instanceId, string activityQualifiedName, string hierarchicalActivityId, ActivityExecutionStatus status, int stateReaderId);
void ScheduleTypeLoaded(Guid programId, Guid scheduleTypeId, string assemblyFullName, string fileName, string md5Digest, bool isDynamic, string scheduleNamespace, string scheduleName, string workflowMarkup);
void UpdateHandlerMethodsForActivity(Guid programId, Guid scheduleTypeId, string activityQualifiedName, List<ActivityHandlerDescriptor> handlerMethods);
void AssemblyLoaded(Guid programId, string assemblyPath, bool fromGlobalAssemblyCache);
void HandlerInvoked(Guid programId, Guid instanceId, int threadId, string activityQualifiedName);
void BeforeHandlerInvoked(Guid programId, Guid scheduleTypeId, string activityQualifiedName, ActivityHandlerDescriptor handlerMethod);
}
#endregion
}

View File

@@ -0,0 +1,35 @@
using System;
using System.Workflow.ComponentModel;
namespace System.Workflow.Runtime.DebugEngine
{
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public interface IWorkflowDebuggerService
{
void NotifyHandlerInvoking(Delegate delegateHandler);
void NotifyHandlerInvoked();
}
internal sealed class WorkflowDebuggerService : IWorkflowDebuggerService
{
private IWorkflowCoreRuntime coreRuntime;
internal WorkflowDebuggerService(IWorkflowCoreRuntime coreRuntime)
{
if (coreRuntime == null)
throw new ArgumentNullException("coreRuntime");
this.coreRuntime = coreRuntime;
}
void IWorkflowDebuggerService.NotifyHandlerInvoking(Delegate delegateHandler)
{
this.coreRuntime.RaiseHandlerInvoking(delegateHandler);
}
void IWorkflowDebuggerService.NotifyHandlerInvoked()
{
this.coreRuntime.RaiseHandlerInvoked();
}
}
}

View File

@@ -0,0 +1,119 @@
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
#region Using directives
using System;
using System.Runtime.InteropServices;
using System.Workflow.ComponentModel;
using System.Workflow.ComponentModel.Design;
#endregion
namespace System.Workflow.Runtime.DebugEngine
{
internal static class NativeMethods
{
public const int STANDARD_RIGHTS_REQUIRED = (0x000F0000);
public const int TOKEN_ASSIGN_PRIMARY = (0x0001);
public const int TOKEN_DUPLICATE = (0x0002);
public const int TOKEN_IMPERSONATE = (0x0004);
public const int TOKEN_QUERY = (0x0008);
public const int TOKEN_QUERY_SOURCE = (0x0010);
public const int TOKEN_ADJUST_PRIVILEGES = (0x0020);
public const int TOKEN_ADJUST_GROUPS = (0x0040);
public const int TOKEN_ADJUST_DEFAULT = (0x0080);
public const int TOKEN_ADJUST_SESSIONID = (0x0100);
public const int TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED |
TOKEN_ASSIGN_PRIMARY |
TOKEN_DUPLICATE |
TOKEN_IMPERSONATE |
TOKEN_QUERY |
TOKEN_QUERY_SOURCE |
TOKEN_ADJUST_PRIVILEGES |
TOKEN_ADJUST_GROUPS |
TOKEN_ADJUST_DEFAULT);
[Flags]
public enum SECURITY_INFORMATION : uint
{
OWNER_SECURITY_INFORMATION = 0x00000001,
GROUP_SECURITY_INFORMATION = 0x00000002,
DACL_SECURITY_INFORMATION = 0x00000004,
SACL_SECURITY_INFORMATION = 0x00000008,
UNPROTECTED_SACL_SECURITY_INFORMATION = 0x10000000,
UNPROTECTED_DACL_SECURITY_INFORMATION = 0x20000000,
PROTECTED_SACL_SECURITY_INFORMATION = 0x40000000,
PROTECTED_DACL_SECURITY_INFORMATION = 0x80000000
}
[Flags]
public enum RpcAuthnLevel
{
Default = 0,
None = 1,
Connect = 2,
Call = 3,
Pkt = 4,
PktIntegrity = 5,
PktPrivacy = 6
}
public enum EoAuthnCap
{
None = 0x00,
MutualAuth = 0x01,
StaticCloaking = 0x20,
DynamicCloaking = 0x40,
AnyAuthority = 0x80,
MakeFullSIC = 0x100,
Default = 0x800,
SecureRefs = 0x02,
AccessControl = 0x04,
AppID = 0x08,
Dynamic = 0x10,
RequireFullSIC = 0x200,
AutoImpersonate = 0x400,
NoCustomMarshal = 0x2000,
DisableAAA = 0x1000
}
public enum RpcImpLevel
{
Default = 0,
Anonymous = 1,
Identify = 2,
Impersonate = 3,
Delegate = 4
}
[DllImport("kernel32.dll", SetLastError = false)]
public static extern int GetCurrentThreadId();
[DllImport("kernel32.dll", SetLastError = false)]
public static extern IntPtr GetCurrentProcess();
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool RevertToSelf();
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool GetKernelObjectSecurity(IntPtr Handle, SECURITY_INFORMATION RequestedInformation, IntPtr pSecurityDescriptor, UInt32 nLength, out UInt32 lpnLengthNeeded);
[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool SetKernelObjectSecurity(IntPtr Handle, SECURITY_INFORMATION SecurityInformation, IntPtr SecurityDescriptor);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CloseHandle(IntPtr hObject);
}
internal static class Guids
{
internal const string CLSID_WDEProgramPublisher = "B6C0E598-314D-4b63-8C5C-4014F2A1B737";
public const string IID_IWDEProgramNode = "e5e93adb-a6fe-435e-8640-31ae310d812f";
public const string IID_IWDEProgramPublisher = "2BE74789-F70B-42a3-80CA-E91743385844";
}
}

View File

@@ -0,0 +1,33 @@
// Copyright (c) Microsoft Corp., 2004. All rights reserved.
#region Using directives
using System;
using System.Threading;
using System.Reflection;
using System.Runtime.InteropServices;
#endregion
namespace System.Workflow.Runtime.DebugEngine
{
internal sealed class ProgramNode : IWDEProgramNode
{
private DebugController controller;
public ProgramNode(DebugController controller)
{
this.controller = controller;
}
void IWDEProgramNode.Attach(ref Guid programId, int attachTimeout, int detachPingInterval, out string hostName, out string uri, out int controllerThreadId, out bool isSynchronousAttach)
{
this.controller.Attach(programId, attachTimeout, detachPingInterval, out hostName, out uri, out controllerThreadId, out isSynchronousAttach);
}
}
[ComImport(), Guid(Guids.IID_IWDEProgramNode), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
internal interface IWDEProgramNode
{
void Attach(ref Guid programId, int attachTimeout, int detachPingInterval, [Out, MarshalAs(UnmanagedType.BStr)] out string hostName, [Out, MarshalAs(UnmanagedType.BStr)] out string uri, [Out] out int controllerThreadId, [Out, MarshalAs(UnmanagedType.Bool)] out bool isSynchronousAttach);
}
}

View File

@@ -0,0 +1,140 @@
// 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);
}
}

View File

@@ -0,0 +1,32 @@
using System;
namespace System.Workflow.Runtime.DebugEngine
{
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public enum WorkflowDebuggerSteppingOption
{
Sequential = 0,
Concurrent = 1
}
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = true)]
[Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
public sealed class WorkflowDebuggerSteppingAttribute : Attribute
{
private WorkflowDebuggerSteppingOption steppingOption;
public WorkflowDebuggerSteppingAttribute(WorkflowDebuggerSteppingOption steppingOption)
{
this.steppingOption = steppingOption;
}
public WorkflowDebuggerSteppingOption SteppingOption
{
get
{
return this.steppingOption;
}
}
}
}