I made a DDE server sample with timer.
using System;
using System.Windows.Forms;
using NDde.Server;
using System.Timers;
namespace DDEServer_Test
{
public partial class DDEServer_MainForm : Form
{
public DDEServer_MainForm()
{
InitializeComponent();
}
public void runDDEServer()
{
try
{
using (DdeServer server = new theDDEServer("dde_server"))
{
server.Register();
}
}
catch (Exception ex)
{
}
}
public void dispServerName(string serverName = "")
{
if (textBox1.InvokeRequired)
{
textBox1.Invoke((MethodInvoker)delegate { textBox1.Text = serverName; });
}
else
{
this.textBox1.Text = serverName;
}
//this.textBox1.Text = serverName;
}
public void dispTopicName(string topicName = "")
{
if (textBox2.InvokeRequired)
{
textBox2.Invoke((MethodInvoker)delegate { textBox2.Text = topicName; });
}
else
{
this.textBox2.Text = topicName;
}
//this.textBox2.Text = topicName;
}
public void dispItemName(string itemName = "")
{
if (textBox3.InvokeRequired)
{
textBox3.Invoke((MethodInvoker)delegate { textBox3.Text = itemName; });
}
else
{
this.textBox3.Text = itemName;
}
//this.textBox3.Text = itemName;
}
public void dispHandleString(string handleString = "")
{
if (textBox4.InvokeRequired)
{
textBox4.Invoke((MethodInvoker)delegate { textBox4.Text = handleString; });
}
else
{
this.textBox4.Text = handleString;
}
//this.textBox4.Text = handleString;
}
public void dispFormatString(string formatString = "")
{
if (textBox5.InvokeRequired)
{
textBox5.Invoke((MethodInvoker)delegate { textBox5.Text = formatString; });
}
else
{
this.textBox5.Text = formatString;
}
//this.textBox5.Text = formatString;
}
public void dispCommandString(string commandString="")
{
if (textBox6.InvokeRequired)
{
textBox6.Invoke((MethodInvoker)delegate { textBox6.Text = commandString; });
}
else
{
this.textBox6.Text = commandString;
}
//this.textBox6.Text = commandString;
}
public void dispDataString(string dataString = "")
{
if (textBox7.InvokeRequired)
{
textBox7.Invoke((MethodInvoker)delegate { textBox7.Text = dataString; });
}
else
{
this.textBox7.Text = dataString;
}
//this.textBox7.Text = dataString;
}
private void button1_Click(object sender, EventArgs e)
{
runDDEServer();
}
//class
public sealed class theDDEServer : DdeServer
{
DDEServer_MainForm mainForm = new DDEServer_MainForm();
private System.Timers.Timer _Timer = new System.Timers.Timer();
public theDDEServer(string service) : base(service)
{
_Timer.Elapsed += this.OnTimerElapsed;
_Timer.Interval = 1000;
_Timer.SynchronizingObject = this.Context;
}
private void OnTimerElapsed(object sender, ElapsedEventArgs args)
{
Advise("*", "*");
}
public override void Register()
{
Console.WriteLine("R");
base.Register();
_Timer.Start();
}
public override void Unregister()
{
_Timer.Stop();
base.Unregister();
}
protected override bool OnBeforeConnect(string topic)
{
Console.WriteLine("Before Connect");
mainForm.dispServerName(base.Service);
mainForm.dispTopicName(topic);
mainForm.dispHandleString();
mainForm.dispHandleString();
mainForm.dispItemName();
mainForm.dispFormatString();
mainForm.dispCommandString();
mainForm.dispDataString();
return true;
}
protected override void OnAfterConnect(DdeConversation conversation)
{
Console.WriteLine("After Connect");
mainForm.dispServerName(conversation.Service);
mainForm.dispTopicName(conversation.Topic);
mainForm.dispHandleString(conversation.Handle.ToString());
mainForm.dispHandleString();
mainForm.dispItemName();
mainForm.dispFormatString();
mainForm.dispCommandString();
mainForm.dispDataString();
}
protected override void OnDisconnect(DdeConversation conversation)
{
Console.WriteLine("Disconnect");
mainForm.dispServerName(conversation.Service);
mainForm.dispTopicName(conversation.Topic);
mainForm.dispHandleString(conversation.Handle.ToString());
mainForm.dispItemName();
mainForm.dispFormatString();
mainForm.dispCommandString();
mainForm.dispDataString();
}
protected override bool OnStartAdvise(DdeConversation conversation, string item, int format)
{
Console.WriteLine("Start Advise");
mainForm.dispServerName(conversation.Service);
mainForm.dispTopicName(conversation.Service);
mainForm.dispHandleString(conversation.Handle.ToString());
mainForm.dispItemName(item);
mainForm.dispFormatString(format.ToString());
mainForm.dispCommandString();
mainForm.dispDataString();
return format == 1;
}
protected override void OnStopAdvise(DdeConversation conversation, string item)
{
Console.WriteLine("Stop Advise");
mainForm.dispServerName(conversation.Service);
mainForm.dispTopicName(conversation.Service);
mainForm.dispHandleString(conversation.Handle.ToString());
mainForm.dispItemName(item);
mainForm.dispFormatString();
mainForm.dispCommandString();
mainForm.dispDataString();
}
protected override ExecuteResult OnExecute(DdeConversation conversation, string command)
{
Console.WriteLine("Execute");
mainForm.dispServerName(conversation.Service);
mainForm.dispTopicName(conversation.Service);
mainForm.dispHandleString(conversation.Handle.ToString());
mainForm.dispItemName();
mainForm.dispFormatString();
mainForm.dispCommandString(command);
mainForm.dispDataString();
return ExecuteResult.Processed;
}
protected override PokeResult OnPoke(DdeConversation conversation, string item, byte[] data, int format)
{
Console.WriteLine("Poke");
mainForm.dispServerName(conversation.Service);
mainForm.dispTopicName(conversation.Service);
mainForm.dispHandleString(conversation.Handle.ToString());
mainForm.dispItemName(item);
mainForm.dispFormatString(format.ToString());
mainForm.dispCommandString();
mainForm.dispDataString(data.Length.ToString());
return PokeResult.Processed;
}
protected override RequestResult OnRequest(DdeConversation conversation, string item, int format)
{
Console.WriteLine("Request");
mainForm.dispServerName(conversation.Service);
mainForm.dispTopicName(conversation.Service);
mainForm.dispHandleString(conversation.Handle.ToString());
mainForm.dispItemName(item);
mainForm.dispFormatString(format.ToString());
mainForm.dispCommandString();
mainForm.dispDataString();
if (format == 1)
{
return new RequestResult(System.Text.Encoding.ASCII.GetBytes("Now = " + DateTime.Now.ToString() + "\0"));
}
return RequestResult.NotProcessed;
}
protected override byte[] OnAdvise(string topic, string item, int format)
{
Console.WriteLine("Advise");
mainForm.dispServerName(this.Service);
mainForm.dispTopicName(topic);
mainForm.dispHandleString(item);
mainForm.dispItemName(item);
mainForm.dispFormatString(format.ToString());
mainForm.dispCommandString();
mainForm.dispDataString();
if (format == 1)
{
return System.Text.Encoding.ASCII.GetBytes("Now = " + DateTime.Now.ToString() + "\0");
}
return null;
}
public void TargetInvocationException(Exception inner)
{
MessageBox.Show(inner.Message);
}
}
}
}
After clicking the button to start running the DDE server. The console printed "R", which means it run the Register() and the _Timer has started. The error message 'System.Reflection.TargetInvocationException' in mscorlib.dll came out, and the process was stopped at Advise("", "");
There is no Invoke() method in Advise() and _Timer either. Please help me to solve the problem. Thanks.
It looks like you've got some containment/lifetime issues. The form creates a theDdeServer, and then the theDdeServer creates a different instance of the main form (but never shows it). That doesn't look right. You might want to pass the form to the server on construction
But the most likely cause is that the form creates the theDdeServer and then immediately disposes it:
public void runDDEServer()
{
try
{
using (DdeServer server = new theDDEServer("dde_server"))
{
server.Register();
}
}
catch (Exception ex)
{
}
}
At the closing brace of the using
block, .Net will destroy your server. You don't want to use a using
here. Instead, you want the form to hold onto the server...and then get rid of it when the form is disposed. Something like:
public partial class DDEServer_MainForm : Form
{
DdeServer server;
/* snipped out code */
public void runDDEServer()
{
try
{
server = new theDDEServer("dde_server", this);
server.Register();
}
catch (Exception ex)
{
//--> you should definitely do something here. Print a message at least!
}
}
/* snipped out code */
//--> In the form designer, hook this method to the OnClosing event!
private void closeForm(object sender, System.ComponentModel.CancelEventArgs e)
{
server.Unregister();
server.Dispose();
}
}
And then, in theDdeServer, take the form as a constructor argument:
public sealed class theDDEServer : DdeServer
{
DDEServer_MainForm mainForm;
System.Timers.Timer _Timer = new System.Timers.Timer();
public theDDEServer(string service, Form mainForm) : base(service)
{
DDEServer_MainForm = mainForm;
_Timer.Elapsed += this.OnTimerElapsed;
_Timer.Interval = 1000;
_Timer.SynchronizingObject = this.Context;
}
/* snipped out code */
public override void Unregister()
{
DDEServer_MainForm = null;
_Timer.Stop();
base.Unregister();
}
/* snipped out code */
}