进程之间发送消息
使用到的Window API
1.ChangeWindowMessageFilterEx
2.FindWindow
3.PostMessage
直接上代码
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[DllImport("user32.dll")]
public static extern bool ChangeWindowMessageFilterEx(IntPtr HWnd, uint Msg, int WParam, IntPtr LParam);
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
[DllImport("user32.dll", SetLastError = true)]
public static extern bool PostMessage(IntPtr hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
[DllImport("user32.dll", EntryPoint = "FindWindow")]
[DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
private extern static IntPtr FindWindow(string lpClassName, string lpWindowName);
public struct COPYDATASTRUCT
{
public IntPtr dwData; //not used
public int cbData; //长度
[MarshalAs(UnmanagedType.LPStr)]
public string lpData;
}
A进程
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
//注册发送消息的值
NativeMethods.ChangeWindowMessageFilterEx(mainHwnd, MessageHelper.ShowUserCenterWindow, NativeMethods.MSGFLT_ALLOW, IntPtr.Zero);
}
///接收消息
[HandleProcessCorruptedStateExceptions, SecurityCritical]
private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
{
try
{
switch (msg)
{
case MessageHelper.ShowUserCenterWindow:
//写自己的逻辑
break;
default:
break;
}
}
catch (Exception ex)
{
LogsHelper.Instance.ErrorWrite($"windowsmanager.MainWindow.WndProc Exception:{ex.Message}");
}
return IntPtr.Zero;
}
B进程
//需要发送消息的地方调用
SendMessageToApp("A进程主窗口的名称", MessageHelper.ShowUserCenterWindow);
public bool SendMessageToApp(string WindowTitle, int msg)
{
bool result = false;
var handlePtr = FindWindow(null, WindowTitle);
if (handlePtr != IntPtr.Zero)
result = MessagePacking(handlePtr, msg);
return result;
}
private bool MessagePacking(IntPtr hwnd, int customMsg, int arg = 0)
{
bool result = false;
if (hwnd != IntPtr.Zero)
{
COPYDATASTRUCT cds = new COPYDATASTRUCT();
result = PostMessage(hwnd, customMsg, arg, ref cds);
}
return result;
}
使用时,忘记使用ChangeWindowMessageFilterEx注册消息了,找了好长时间原因,最后还是请教大佬才解决了,特此记录,以备参考。