mirror of
https://github.com/danbulant/Cosmos
synced 2026-06-13 19:52:25 +00:00
This commit is contained in:
parent
a469a39eaf
commit
767d8cd205
5 changed files with 69 additions and 69 deletions
|
|
@ -49,7 +49,7 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
EAX.Push();
|
||||
|
||||
// Noop has no data at all (see notes in client DebugConnector), so skip Command ID
|
||||
AL.Compare(DsCommand.Noop);
|
||||
AL.Compare(DsCmd.Noop);
|
||||
JumpIf(Flags.Equal, ".End");
|
||||
|
||||
// Read Command ID
|
||||
|
|
@ -58,17 +58,17 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
|
||||
// Get AL back so we can compare it, but also put it back for later
|
||||
EAX = ESP[0];
|
||||
CheckCmd(DsCommand.TraceOff, typeof(TraceOff));
|
||||
CheckCmd(DsCommand.TraceOn, typeof(TraceOn));
|
||||
CheckCmd(DsCommand.Break, typeof(Break));
|
||||
CheckCmd(DsCommand.BreakOnAddress, typeof(BreakOnAddress));
|
||||
CheckCmd(DsCommand.SendMethodContext, typeof(SendMethodContext));
|
||||
CheckCmd(DsCommand.SendMemory, typeof(SendMemory));
|
||||
CheckCmd(DsCommand.SendRegisters, typeof(SendRegisters));
|
||||
CheckCmd(DsCommand.SendFrame, typeof(SendFrame));
|
||||
CheckCmd(DsCommand.SendStack, typeof(SendStack));
|
||||
CheckCmd(DsCommand.SetAsmBreak, typeof(SetAsmBreak));
|
||||
CheckCmd(DsCommand.Ping, typeof(Ping));
|
||||
CheckCmd(DsCmd.TraceOff, typeof(TraceOff));
|
||||
CheckCmd(DsCmd.TraceOn, typeof(TraceOn));
|
||||
CheckCmd(DsCmd.Break, typeof(Break));
|
||||
CheckCmd(DsCmd.BreakOnAddress, typeof(BreakOnAddress));
|
||||
CheckCmd(DsCmd.SendMethodContext, typeof(SendMethodContext));
|
||||
CheckCmd(DsCmd.SendMemory, typeof(SendMemory));
|
||||
CheckCmd(DsCmd.SendRegisters, typeof(SendRegisters));
|
||||
CheckCmd(DsCmd.SendFrame, typeof(SendFrame));
|
||||
CheckCmd(DsCmd.SendStack, typeof(SendStack));
|
||||
CheckCmd(DsCmd.SetAsmBreak, typeof(SetAsmBreak));
|
||||
CheckCmd(DsCmd.Ping, typeof(Ping));
|
||||
|
||||
Label = ".SendACK";
|
||||
// We acknowledge receipt of the command, not processing of it.
|
||||
|
|
@ -81,7 +81,7 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
// We may need to revisit this in the future to ack not commands, but data chunks
|
||||
// and move them to a buffer.
|
||||
// The buffer problem exists only to inbound data, not outbound data (relative to DebugStub)
|
||||
AL = DsMsgType.CmdCompleted;
|
||||
AL = DsMsg.CmdCompleted;
|
||||
Call<WriteALToComPort>();
|
||||
//
|
||||
EAX = DebugStub_CommandID.Value;
|
||||
|
|
@ -202,7 +202,7 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
// 2: x32 - size of data to send
|
||||
[XSharp(PreserveStack = true)]
|
||||
public override void Assemble() {
|
||||
AL = (int)DsMsgType.MethodContext;
|
||||
AL = (int)DsMsg.MethodContext;
|
||||
Call<WriteALToComPort>();
|
||||
|
||||
// offset relative to ebp
|
||||
|
|
@ -235,7 +235,7 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
public override void Assemble() {
|
||||
ReadComPortX32toStack(1);
|
||||
Label = "DebugStub_SendMemory_1";
|
||||
AL = (int)DsMsgType.MemoryData;
|
||||
AL = (int)DsMsg.MemoryData;
|
||||
Call<WriteALToComPort>();
|
||||
|
||||
ReadComPortX32toStack(1);
|
||||
|
|
@ -263,11 +263,11 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
public override void Assemble() {
|
||||
DebugStatus.Value.Compare(Status.Run);
|
||||
JumpIf(Flags.Equal, ".Normal");
|
||||
AL = (int)DsMsgType.BreakPoint;
|
||||
AL = (int)DsMsg.BreakPoint;
|
||||
Jump(".Type");
|
||||
|
||||
Label = ".Normal";
|
||||
AL = (int)DsMsgType.TracePoint;
|
||||
AL = (int)DsMsg.TracePoint;
|
||||
|
||||
Label = ".Type";
|
||||
Call<WriteALToComPort>();
|
||||
|
|
@ -284,7 +284,7 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
// Modifies: EAX, ECX, EDX, ESI
|
||||
public override void Assemble() {
|
||||
// Write the type
|
||||
AL = (int)DsMsgType.Message;
|
||||
AL = (int)DsMsg.Message;
|
||||
Call<WriteALToComPort>();
|
||||
|
||||
// Write Length
|
||||
|
|
@ -313,7 +313,7 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
// Modifies: EAX, ECX, EDX, ESI
|
||||
public override void Assemble() {
|
||||
// Write the type
|
||||
AL = (int)DsMsgType.Pointer;
|
||||
AL = (int)DsMsg.Pointer;
|
||||
Call<WriteALToComPort>();
|
||||
|
||||
// pointer value
|
||||
|
|
@ -409,7 +409,7 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
|
||||
// We could use the signature as the start signal, but I prefer
|
||||
// to keep the logic separate, especially in DC.
|
||||
AL = (int)DsMsgType.Started; // Send the actual started signal
|
||||
AL = (int)DsMsg.Started; // Send the actual started signal
|
||||
Call<WriteALToComPort>();
|
||||
|
||||
Call<WaitForSignature>();
|
||||
|
|
@ -574,7 +574,7 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
Call<ProcessCommand>();
|
||||
|
||||
// See if batch is complete
|
||||
AL.Compare(DsCommand.BatchEnd);
|
||||
AL.Compare(DsCmd.BatchEnd);
|
||||
JumpIf(Flags.Equal, "DebugStub_ProcessCommandBatch_Exit");
|
||||
|
||||
// Loop and wait
|
||||
|
|
@ -621,7 +621,7 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
|
||||
public class SendRegisters : Inlines {
|
||||
public override void Assemble() {
|
||||
AL = (int)DsMsgType.Registers; // Send the actual started signal
|
||||
AL = (int)DsMsg.Registers; // Send the actual started signal
|
||||
Call<WriteALToComPort>();
|
||||
|
||||
ESI = DebugPushAllPtr.Value;
|
||||
|
|
@ -635,7 +635,7 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
|
||||
public class SendFrame : Inlines {
|
||||
public override void Assemble() {
|
||||
AL = (int)DsMsgType.Frame;
|
||||
AL = (int)DsMsg.Frame;
|
||||
Call<WriteALToComPort>();
|
||||
|
||||
int xCount = 8 * 4;
|
||||
|
|
@ -650,7 +650,7 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
|
||||
public class SendStack : CodeBlock {
|
||||
public override void Assemble() {
|
||||
AL = (int)DsMsgType.Stack;
|
||||
AL = (int)DsMsg.Stack;
|
||||
Call<WriteALToComPort>();
|
||||
|
||||
// Send size of bytes
|
||||
|
|
@ -703,7 +703,7 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
|
||||
public class Ping : Inlines {
|
||||
public override void Assemble() {
|
||||
AL = DsMsgType.Pong;
|
||||
AL = DsMsg.Pong;
|
||||
Call<WriteALToComPort>();
|
||||
}
|
||||
}
|
||||
|
|
@ -848,16 +848,16 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
// or commands that require additional handling while in break
|
||||
// state.
|
||||
|
||||
AL.Compare(DsCommand.Continue);
|
||||
AL.Compare(DsCmd.Continue);
|
||||
JumpIf(Flags.Equal, "DebugStub_Break_Exit");
|
||||
|
||||
AL.Compare(DsCommand.StepInto);
|
||||
AL.Compare(DsCmd.StepInto);
|
||||
JumpIf(Flags.NotEqual, "DebugStub_Break_StepInto_After");
|
||||
DebugBreakOnNextTrace.Value = StepTrigger.Into;
|
||||
Jump("DebugStub_Break_Exit");
|
||||
Label = "DebugStub_Break_StepInto_After";
|
||||
|
||||
AL.Compare(DsCommand.StepOver);
|
||||
AL.Compare(DsCmd.StepOver);
|
||||
JumpIf(Flags.NotEqual, "DebugStub_Break_StepOver_After");
|
||||
DebugBreakOnNextTrace.Value = StepTrigger.Over;
|
||||
EAX = CallerEBP.Value;
|
||||
|
|
@ -865,7 +865,7 @@ namespace Cosmos.Compiler.DebugStub {
|
|||
Jump("DebugStub_Break_Exit");
|
||||
Label = "DebugStub_Break_StepOver_After";
|
||||
|
||||
AL.Compare(DsCommand.StepOut);
|
||||
AL.Compare(DsCmd.StepOut);
|
||||
JumpIf(Flags.NotEqual, "DebugStub_Break_StepOut_After");
|
||||
DebugBreakOnNextTrace.Value = StepTrigger.Out;
|
||||
EAX = CallerEBP.Value;
|
||||
|
|
|
|||
|
|
@ -57,13 +57,13 @@ namespace Cosmos.Debug.Common
|
|||
//System.Windows.Forms.MessageBox.Show(xSB.ToString());
|
||||
DoDebugMsg("DC Send: " + aCmd.ToString());
|
||||
|
||||
if (aCmd == DsCommand.Noop) {
|
||||
if (aCmd == DsCmd.Noop) {
|
||||
// Noops dont have any data.
|
||||
// This is becuase Noops are used to clear out the
|
||||
// channel and are often not received. Sending noop + data
|
||||
// usually causes the data to be interpreted as a command
|
||||
// as its often the first byte received.
|
||||
SendRawData(new byte[1] { DsCommand.Noop });
|
||||
SendRawData(new byte[1] { DsCmd.Noop });
|
||||
} else {
|
||||
var xData = new byte[aData.Length + 2];
|
||||
// See comments about flow control in the DebugStub class
|
||||
|
|
@ -108,17 +108,17 @@ namespace Cosmos.Debug.Common
|
|||
}
|
||||
|
||||
public void SendRegisters() {
|
||||
SendCommand(DsCommand.SendRegisters);
|
||||
SendCommand(DsCmd.SendRegisters);
|
||||
}
|
||||
|
||||
public void SendFrame()
|
||||
{
|
||||
SendCommand(DsCommand.SendFrame);
|
||||
SendCommand(DsCmd.SendFrame);
|
||||
}
|
||||
|
||||
public void SendStack()
|
||||
{
|
||||
SendCommand(DsCommand.SendStack);
|
||||
SendCommand(DsCmd.SendStack);
|
||||
}
|
||||
|
||||
public void SetBreakpoint(int aID, uint aAddress) {
|
||||
|
|
@ -139,7 +139,7 @@ namespace Cosmos.Debug.Common
|
|||
var xData = new byte[5];
|
||||
Array.Copy(BitConverter.GetBytes(aAddress), 0, xData, 0, 4);
|
||||
xData[4] = (byte)aID;
|
||||
SendCommandData(DsCommand.BreakOnAddress, xData, true);
|
||||
SendCommandData(DsCmd.BreakOnAddress, xData, true);
|
||||
}
|
||||
|
||||
public byte[] GetMemoryData(uint address, uint size, int dataElementSize = 1)
|
||||
|
|
@ -166,7 +166,7 @@ namespace Cosmos.Debug.Common
|
|||
mDataSize = (int)size;
|
||||
Array.Copy(BitConverter.GetBytes(address), 0, xData, 0, 4);
|
||||
Array.Copy(BitConverter.GetBytes(size), 0, xData, 4, 4);
|
||||
SendCommandData(DsCommand.SendMemory, xData, true);
|
||||
SendCommandData(DsCmd.SendMemory, xData, true);
|
||||
var xResult = mData;
|
||||
mData = null;
|
||||
if (xResult.Length != size)
|
||||
|
|
@ -198,7 +198,7 @@ namespace Cosmos.Debug.Common
|
|||
|
||||
Array.Copy(BitConverter.GetBytes(offsetToEBP), 0, xData, 0, 4);
|
||||
Array.Copy(BitConverter.GetBytes(size), 0, xData, 4, 4);
|
||||
SendCommandData(DsCommand.SendMethodContext, xData, true);
|
||||
SendCommandData(DsCmd.SendMethodContext, xData, true);
|
||||
// todo: make "crossplatform". this code assumes stack space of 32bit per "item"
|
||||
|
||||
byte[] xResult;
|
||||
|
|
@ -228,18 +228,18 @@ namespace Cosmos.Debug.Common
|
|||
mCurrentMsgType = aPacket[0];
|
||||
// Could change to an array, but really not much benefit
|
||||
switch (mCurrentMsgType) {
|
||||
case DsMsgType.TracePoint:
|
||||
case DsMsgType.BreakPoint:
|
||||
case DsMsg.TracePoint:
|
||||
case DsMsg.BreakPoint:
|
||||
DoDebugMsg("DC Recv: TracePoint / BreakPoint");
|
||||
Next(4, PacketTracePoint);
|
||||
break;
|
||||
|
||||
case DsMsgType.Message:
|
||||
case DsMsg.Message:
|
||||
DoDebugMsg("DC Recv: Message");
|
||||
Next(2, PacketTextSize);
|
||||
break;
|
||||
|
||||
case DsMsgType.Started:
|
||||
case DsMsg.Started:
|
||||
DoDebugMsg("DC Recv: Started");
|
||||
// Call WaitForMessage first, else it blocks becuase started triggers
|
||||
// other commands which need responses.
|
||||
|
|
@ -247,7 +247,7 @@ namespace Cosmos.Debug.Common
|
|||
// Guests never get the first byte sent. So we send a noop.
|
||||
// This dummy byte seems to clear out the serial channel.
|
||||
// Its never received, but if it ever is, its a noop anyways.
|
||||
SendCommand(DsCommand.Noop);
|
||||
SendCommand(DsCmd.Noop);
|
||||
|
||||
// Send signature
|
||||
var xData = new byte[4];
|
||||
|
|
@ -257,7 +257,7 @@ namespace Cosmos.Debug.Common
|
|||
CmdStarted();
|
||||
break;
|
||||
|
||||
case DsMsgType.Noop:
|
||||
case DsMsg.Noop:
|
||||
DoDebugMsg("DC Recv: Noop");
|
||||
// MtW: When implementing Serial support for debugging on real hardware, it appears
|
||||
// that when booting a machine, in the bios it emits zero's to the serial port.
|
||||
|
|
@ -265,37 +265,37 @@ namespace Cosmos.Debug.Common
|
|||
WaitForMessage();
|
||||
break;
|
||||
|
||||
case DsMsgType.CmdCompleted:
|
||||
case DsMsg.CmdCompleted:
|
||||
DoDebugMsg("DC Recv: CmdCompleted");
|
||||
Next(1, PacketCmdCompleted);
|
||||
break;
|
||||
|
||||
case DsMsgType.MethodContext:
|
||||
case DsMsg.MethodContext:
|
||||
DoDebugMsg("DC Recv: MethodContext");
|
||||
Next(mDataSize, PacketMethodContext);
|
||||
break;
|
||||
|
||||
case DsMsgType.MemoryData:
|
||||
case DsMsg.MemoryData:
|
||||
DoDebugMsg("DC Recv: MemoryData");
|
||||
Next(mDataSize, PacketMemoryData);
|
||||
break;
|
||||
|
||||
case DsMsgType.Registers:
|
||||
case DsMsg.Registers:
|
||||
DoDebugMsg("DC Recv: Registers");
|
||||
Next(40, PacketRegisters);
|
||||
break;
|
||||
|
||||
case DsMsgType.Frame:
|
||||
case DsMsg.Frame:
|
||||
DoDebugMsg("DC Recv: Frame");
|
||||
Next(-1, PacketFrame);
|
||||
break;
|
||||
|
||||
case DsMsgType.Stack:
|
||||
case DsMsg.Stack:
|
||||
DoDebugMsg("DC Recv: Stack");
|
||||
Next(-1, PacketStack);
|
||||
break;
|
||||
|
||||
case DsMsgType.Pong:
|
||||
case DsMsg.Pong:
|
||||
DoDebugMsg("DC Recv: Pong");
|
||||
Next(1, PacketPong);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -129,17 +129,17 @@ namespace Cosmos.Debug.VSDebugEngine {
|
|||
public string mProjectFile;
|
||||
|
||||
protected void DbgCmdRegisters(byte[] aData) {
|
||||
DebugWindows.SendCommand(DwMsgType.Registers, aData);
|
||||
DebugWindows.SendCommand(DwMsg.Registers, aData);
|
||||
}
|
||||
|
||||
protected void DbgCmdFrame(byte[] aData)
|
||||
{
|
||||
DebugWindows.SendCommand(DwMsgType.Frame, aData);
|
||||
DebugWindows.SendCommand(DwMsg.Frame, aData);
|
||||
}
|
||||
|
||||
protected void DbgCmdStack(byte[] aData)
|
||||
{
|
||||
DebugWindows.SendCommand(DwMsgType.Stack, aData);
|
||||
DebugWindows.SendCommand(DwMsg.Stack, aData);
|
||||
}
|
||||
|
||||
internal AD7Process(NameValueCollection aDebugInfo, EngineCallback aCallback, AD7Engine aEngine, IDebugPort2 aPort)
|
||||
|
|
@ -301,7 +301,7 @@ namespace Cosmos.Debug.VSDebugEngine {
|
|||
mDbgConnector.SetBreakpoint(xBBP.RemoteID, xBBP.mAddress);
|
||||
}
|
||||
}
|
||||
mDbgConnector.SendCommand(DsCommand.BatchEnd);
|
||||
mDbgConnector.SendCommand(DsCmd.BatchEnd);
|
||||
}
|
||||
|
||||
void DbgCmdText(string obj) {
|
||||
|
|
@ -317,7 +317,7 @@ namespace Cosmos.Debug.VSDebugEngine {
|
|||
void DbgCmdTrace(byte arg1, uint arg2) {
|
||||
DebugMsg("DbgCmdTrace");
|
||||
switch (arg1) {
|
||||
case DsMsgType.BreakPoint: {
|
||||
case DsMsg.BreakPoint: {
|
||||
// When doing a CALL, the return address is pushed, but that's the address of the next instruction, after CALL. call is 5 bytes (for now?)
|
||||
// Dont need to correct the address, becuase DebugStub does it for us.
|
||||
var xActualAddress = arg2;
|
||||
|
|
@ -481,18 +481,18 @@ namespace Cosmos.Debug.VSDebugEngine {
|
|||
|
||||
internal void Continue() { // F5
|
||||
mCurrentAddress = null;
|
||||
mDbgConnector.SendCommand(DsCommand.Continue);
|
||||
mDbgConnector.SendCommand(DsCmd.Continue);
|
||||
}
|
||||
|
||||
internal void Step(enum_STEPKIND aKind) {
|
||||
if (aKind == enum_STEPKIND.STEP_INTO) { // F11
|
||||
mDbgConnector.SendCommand(DsCommand.StepInto);
|
||||
mDbgConnector.SendCommand(DsCmd.StepInto);
|
||||
|
||||
} else if (aKind == enum_STEPKIND.STEP_OVER) { // F10
|
||||
mDbgConnector.SendCommand(DsCommand.StepOver);
|
||||
mDbgConnector.SendCommand(DsCmd.StepOver);
|
||||
|
||||
} else if (aKind == enum_STEPKIND.STEP_OUT) { // Shift-F11
|
||||
mDbgConnector.SendCommand(DsCommand.StepOut);
|
||||
mDbgConnector.SendCommand(DsCmd.StepOut);
|
||||
|
||||
} else if (aKind == enum_STEPKIND.STEP_BACKWARDS) {
|
||||
// STEP_BACKWARDS - Supported at all by VS?
|
||||
|
|
@ -571,7 +571,7 @@ namespace Cosmos.Debug.VSDebugEngine {
|
|||
}
|
||||
}
|
||||
// Send source code to the tool window
|
||||
DebugWindows.SendCommand(DwMsgType.AssemblySource, Encoding.ASCII.GetBytes(xCode.ToString()));
|
||||
DebugWindows.SendCommand(DwMsg.AssemblySource, Encoding.ASCII.GetBytes(xCode.ToString()));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ namespace Cosmos.Compiler.Debug {
|
|||
}
|
||||
|
||||
// Messages from Guest (Cosmos) to Host (VS)
|
||||
static public class DsMsgType {
|
||||
static public class DsMsg {
|
||||
public const byte Noop = 0;
|
||||
public const byte TracePoint = 1;
|
||||
public const byte Message = 2;
|
||||
|
|
@ -30,7 +30,7 @@ namespace Cosmos.Compiler.Debug {
|
|||
}
|
||||
|
||||
// Messages from Host (VS) to Guest (Cosmos)
|
||||
static public class DsCommand {
|
||||
static public class DsCmd {
|
||||
public const byte Noop = 0;
|
||||
public const byte TraceOff = 1;
|
||||
public const byte TraceOn = 2;
|
||||
|
|
@ -55,7 +55,7 @@ namespace Cosmos.Compiler.Debug {
|
|||
}
|
||||
|
||||
// Commands from VS Debug Engine to VS Debug Window
|
||||
static public class DwMsgType {
|
||||
static public class DwMsg {
|
||||
public const byte Noop = 0;
|
||||
public const byte Registers = 1;
|
||||
public const byte AssemblySource = 3;
|
||||
|
|
|
|||
|
|
@ -187,10 +187,10 @@ namespace Cosmos.Cosmos_VS_Windows
|
|||
xMsg = mMessage.Dequeue();
|
||||
}
|
||||
switch (xCmd) {
|
||||
case DwMsgType.Noop:
|
||||
case DwMsg.Noop:
|
||||
break;
|
||||
|
||||
case DwMsgType.Stack:
|
||||
case DwMsg.Stack:
|
||||
if (StackTW.mUC != null)
|
||||
{
|
||||
StackTW.mUC.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate()
|
||||
|
|
@ -204,7 +204,7 @@ namespace Cosmos.Cosmos_VS_Windows
|
|||
}
|
||||
break;
|
||||
|
||||
case DwMsgType.Frame:
|
||||
case DwMsg.Frame:
|
||||
if (StackTW.mUC != null)
|
||||
{
|
||||
StackTW.mUC.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate()
|
||||
|
|
@ -218,7 +218,7 @@ namespace Cosmos.Cosmos_VS_Windows
|
|||
}
|
||||
break;
|
||||
|
||||
case DwMsgType.Registers:
|
||||
case DwMsg.Registers:
|
||||
if (RegistersTW.mUC != null)
|
||||
{
|
||||
RegistersTW.mUC.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate()
|
||||
|
|
@ -232,11 +232,11 @@ namespace Cosmos.Cosmos_VS_Windows
|
|||
}
|
||||
break;
|
||||
|
||||
case DwMsgType.Quit:
|
||||
case DwMsg.Quit:
|
||||
//Close();
|
||||
break;
|
||||
|
||||
case DwMsgType.AssemblySource:
|
||||
case DwMsg.AssemblySource:
|
||||
if (AssemblyTW.mUC != null)
|
||||
{
|
||||
AssemblyTW.mUC.Dispatcher.Invoke(DispatcherPriority.Normal, (Action)delegate()
|
||||
|
|
|
|||
Loading…
Reference in a new issue