• C#使用SendMessage进行进程间通讯


    最近公司有个需求是,拖动文件到桌面图标上,自动打开文件。那么只需在OnStartup事件中通过StartupEventArgs获取文件名然后进行操作即可。操作之后发现当软件已经启动了(单例运行),那么将无法将参数传给业务层。原因是因为跨进程了,那么我们可以通过窗口句柄的方式来进行通讯。

    复制代码
     1  public partial class App : Application
     2  {
     3      private static Mutex AppMutex;
     4      public App()
     5      {
     6 
     7      }
     8 
     9      protected override void OnStartup(StartupEventArgs e)
    10      {
    11          //获取启动参数
    12          var param = string.Empty;
    13          if (e.Args.Length > 0)
    14          {
    15              param = e.Args[0].ToString();
    16          }
    17 
    18          //WpfApp8 = 你的项目名称
    19          AppMutex = new Mutex(true, "WpfApp8", out var createdNew);
    20 
    21          if (!createdNew)
    22          {
    23              var current = Process.GetCurrentProcess();
    24 
    25              foreach (var process in Process.GetProcessesByName(current.ProcessName))
    26              {
    27                  if (process.Id != current.Id)
    28                  { 
    29                      Win32Helper.SetForegroundWindow(process.MainWindowHandle);
    30                      Win32Helper.SendMessageString(process.MainWindowHandle, param);
    31                      break;
    32                  }
    33              }
    34              Environment.Exit(0);
    35          }
    36          else
    37          {
    38              base.OnStartup(e);
    39          }
    40      }
    41  }
    复制代码
    复制代码
     1  public class Win32Helper
     2  {
     3      [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
     4      public static extern bool SetForegroundWindow(IntPtr hWnd);
     5 
     6      /// 
     7      /// 发送消息
     8      /// 
     9      /// 
    10      /// 
    11      /// 
    12      /// 
    13      /// 
    14      [DllImport("user32.dll")]
    15      public static extern IntPtr SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
    16 
    17      // 声明常量
    18      public const int WM_COPYDATA = 0x004A; 
    19 
    20      // 定义 COPYDATASTRUCT 结构
    21      [StructLayout(LayoutKind.Sequential)]
    22      public struct COPYDATASTRUCT
    23      {
    24          public IntPtr dwData;
    25          public int cbData;
    26          public IntPtr lpData;
    27      }
    28 
    29      /// 
    30      /// 发送字符串消息
    31      /// 
    32      /// 
    33      /// 
    34      public static void SendMessageString(IntPtr hWnd, string message)
    35      {
    36          if (string.IsNullOrEmpty(message)) return;
    37 
    38          byte[] messageBytes = Encoding.Unicode.GetBytes(message + '\0'); // 添加终止符
    39 
    40          COPYDATASTRUCT cds = new COPYDATASTRUCT();
    41          cds.dwData = IntPtr.Zero;
    42          cds.cbData = messageBytes.Length;
    43          cds.lpData = Marshal.AllocHGlobal(cds.cbData);
    44          Marshal.Copy(messageBytes, 0, cds.lpData, cds.cbData);
    45          try
    46          {
    47              SendMessage(hWnd, WM_COPYDATA, IntPtr.Zero, ref cds);
    48          }
    49          finally
    50          {
    51              //释放分配的内存,即使发生异常也不会泄漏资源
    52              Marshal.FreeHGlobal(cds.lpData);
    53          }
    54      } 
    55  }
    复制代码
    复制代码
     1  public partial class MainWindow : Window
     2  {
     3      public MainWindow()
     4      {
     5          InitializeComponent();
     6      }
     7 
     8      protected override void OnSourceInitialized(EventArgs e)
     9      {
    10          base.OnSourceInitialized(e);
    11 
    12          HwndSource hwndSource = PresentationSource.FromVisual(this) as HwndSource;
    13          hwndSource.AddHook(WndProc);
    14      }
    15 
    16      private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
    17      {
    18          if (msg == WM_COPYDATA)
    19          {
    20              COPYDATASTRUCT cds = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, typeof(COPYDATASTRUCT));
    21              string receivedMessage = Marshal.PtrToStringUni(cds.lpData);
    22 
    23              Console.WriteLine("收到消息:" + receivedMessage);
    24 
    25              //TODO:业务处理
    26              MessageBox.Show(receivedMessage);
    27 
    28              handled = true;
    29          }
    30 
    31          return IntPtr.Zero;
    32      }
    33  }
    复制代码

  • 相关阅读:
    21年-05-自研-自我准备
    MySQL恢复不小心误删的数据记录(binlog)-生产实操
    微信小程序支付及退款整体流程
    记一个src中危-图像大小与请求参数可修改
    隧道放样方法
    Flink(java版)
    电脑静态ip地址在哪里找
    Ae 动态图形模板
    Python学习笔记 - 异常处理
    代码随想录Day39-动态规划:力扣第583m、72h、647m、516m、739m题
  • 原文地址:https://www.cnblogs.com/wihalo/p/18293731