Я пытаюсь установить связь между двумя приложениями C#/.NET 3.5 с использованием сообщений Windows, но сообщения, которые я отправляю, появляются некоторое время (но не все время) - почему это происходит, и как я могу гарантировать, что сообщения будут правильно обрабатываться все время. У меня есть объект клиента следующим образом:Сообщения WM_COPYDATA не обрабатываются
[DllImport("User32.dll", EntryPoint = "FindWindow")]
public static extern Int32 FindWindow(String lpClassName, String lpWindowName);
[DllImport("User32.dll", EntryPoint = "SendMessage")]
public static extern IntPtr SendMessage(IntPtr hWindow, int message, IntPtr wParam, IntPtr lParam);
public class WMTCPBridge
{
private IntPtr TargetHwnd
public void SendNumericMessage(Int32 messageCode,
Int32 MessagePayload)
{
//for some reason String.fomat("blah 0x{0:X}",TargetHwnd) shows the number in decimal
string sendNotice = String.Format("Sending to window 0x{0}", TargetHwnd.ToString("X"));
myTextOutput.Writeline(sendNotice);
sendNotice = String.Format("Sending to window {0}", TargetHwnd);
myTextOutput.Writeline(sendNotice);
IntPtr unmanagedInt = Marshal.AllocHGlobal(sizeof(Int32));
Marshal.WriteInt32(unmanagedInt,MessagePayload);
IntPtr result = IntPtr.Zero;
try
{
result = SendMessage(TargetHwnd, WM_COPYDATA, (IntPtr)messageCode,
unmanagedInt);
}
finally
{
Marshal.FreeHGlobal(unmanagedInt);
}
myTextOutput.Writeline("Result is " + result);
if ((int)result == 0)
{
myTextOutput.Writeline("Error code : " + GetThreadError());
}
}
public void GetTargetHandle(string targetName)
{
TargetHwnd = (IntPtr)FindWindow(null, targetName);
if (TargetHwnd == null)
{
myTextOutput.Writeline("Could not connect to UI");
}
else
{
String outputLine = string.Format("Connected to window number 0x{0}", TargetHwnd.ToString("X"));
myTextOutput.Writeline(outputLine);
outputLine = string.Format("Connected to window number {0}", TargetHwnd);
myTextOutput.Writeline(outputLine);
}
}
}
Основная форма моего тестового приложения владеет объектом типа WMTCPBridge, начинается общение по телефону GetTargetHandle и отправляет отдельные сообщения путем вызова метода SendNumericMessage. Сервер является тестовым жгутом, который поддерживает существующее приложение, которое я хотел бы избежать ненужных изменений. Это существующее приложение управляет выбором интерфейса (я должен использовать WM_COPYDATA, я должен отправить код типа сообщения через wparam, если я хочу отправить одно целое число, я должен отправить целое число через lparam вместо Copydatastruct). Основная форма применения серверного метод WndProc переопределена следующим образом:
protected override void WndProc(ref Message m)
{
Int32 messageCode=0;
Int32 messagePayload=0;
Debug.WriteLine(m);
switch (m.Msg)
{
case WM_COPYDATA:
{
messageCode = (int)m.WParam;
messagePayload = Marshal.ReadInt32(m.LParam);
WriteLine("Received message with code " + messageCode +
" and payload " + messagePayload);
break;
}
case WM_CLOSE:
{
WriteLine("Close blocked!");
return;
break;
}
}
base.WndProc(ref m);
}
Когда я запускать сервер и клиент вместе, клиент сообщает, что он посылает сообщения для обработки, что я могу увидеть, Winspector является дескриптор окна сервера, функция sendMessage возвращает 0, а ошибка приложения - 0. Часто сервер не сообщает о получении каких-либо сообщений, а Winspector не показывает никаких сообщений WM_COPYDATA, отправляемых на сервер. Однако, если я продолжаю отправлять сообщения от клиента, некоторые будут получены сервером - у меня обычно есть полосы, где либо все сообщения проходят, либо ничего не делают. Когда я изменил клиент для отправки сообщений WM_CLOSE, сервер неизбежно получит их и закроет - даже когда я попытался захватить сообщения WM_CLOSE с помощью метода WndProc, как показано выше.
Что происходит с моими сообщениями? Я особенно смущен, потому что MSDN говорит, что функция SendMessage возвращается только после обработки сообщения.
Я только что попробовал с фактической COPYDATASTRUCT, и это сработало - спасибо. – Andrew