zoukankan      html  css  js  c++  java
  • C# 进程之间的通讯

    该方法针对同一台服务器上的2个进程之间的通讯,进程A是一个实时采集程序,可能由于某个异常或运行时间过长导致程序卡死,现需要启动另外一个进程B来对

    进程A进行定时监控,如果发现A卡死或无故退出,则自动启动进程A。

    进程A的代码如下:

        public struct COPYDATASTRUCT
        {
    
            public IntPtr dwData;
    
            public int cbData;
    
            [MarshalAs(UnmanagedType.LPStr)]
    
            public string lpData;
    
        }
    
    
            [DllImport("User32.dll", EntryPoint = "FindWindow")]
            public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
    
            [DllImport("user32", EntryPoint = "GetWindowThreadProcessId")]
            public static extern int GetWindowThreadProcessId(IntPtr hwnd, out int pid);
    
            [DllImport("User32.dll", EntryPoint = "SendMessage")]
            //用SendMessage发送消息必须是针对有窗体显示的进程才可以发送成功
            private static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam);
    
            //用 PostThreadMessage 可以给无窗体的主线程发送消息
            [return: MarshalAs(UnmanagedType.Bool)]
            [DllImport("user32.dll", SetLastError = true)]
            public static extern bool PostThreadMessage(int threadId, uint msg, IntPtr wParam, IntPtr lParam);
    
    
            const int WM_COPYDATA = 0x004A;
    
            /// <summary>
            ///  给进程 DCZKStart.exe 发送消息
            /// </summary>
            /// <param name="iflag">消息标记,可以是任意整数值,这个固定0 </param>
            /// <param name="msg">消息内容</param>
            private void SendMsgToProcess(int iflag,string msg="")      
            { 
                //利用发送消息方式,给进程 DCZKStart.exe 发送心跳 
                try
                {
                    int ihwd = GetDCZKStartProcessHandle();
                    byte[] sarr = System.Text.Encoding.Default.GetBytes(msg);
                    int len = sarr.Length;
                    COPYDATASTRUCT cds;
    
                    cds.dwData = (IntPtr)Convert.ToInt16(iflag.ToString());//可以是任意值 
                    cds.cbData = len + 1;//指定lpData内存区域的字节数 
                    cds.lpData = msg;//发送给目标窗口所在进程的数据
    
                    SendMessage(ihwd, WM_COPYDATA, 0, ref cds);
                }
                catch(Exception ex)
                {
                    ShowLogInfo(ex.Message, true);
                } 
            }
    
    
            private int GetDCZKStartProcessHandle() //获取进程 DCZKStart.exe 的进程句柄
            {
                int ihWnd = -1;
    
                try
                {
                    Process p = Process.GetProcessesByName("DCZKStart")[0];
                    if (p!=null)
                    {                    
                        IntPtr hwnd = p.MainWindowHandle;   
                        //如果窗体最小化,这根据窗体名称来查找
                        if (hwnd==IntPtr.Zero)
                        {
                            hwnd = FindWindow(null, "DCZKStart_V3");
                            if (hwnd!=IntPtr.Zero)
                            {
                                ihWnd = (int)hwnd; 
                            }
                        }
                        else
                        {
                            ihWnd = (int)hwnd; 
                        }
                    }
                }
                catch (Exception ex)
                {
                    ShowLogInfo(ex.Message, true);
                }
                return ihWnd;
            }

    其中函数  SendMsgToProcess  就是用来给进程B发送通知消息的,这个消息定时30秒发送一次,以此来告诉进程B它还活着。

    这里有一点要注意:就是想要利用SendMessage来发送消息,接收方必须要有窗体,如果窗体隐藏了,则需要通过 FindWindow 来获取窗体句柄。

    进程B的代码:

            /// <summary>
            /// 消息接受处理函数
            /// </summary>
            /// <param name="m"></param>
            protected override void DefWndProc(ref Message m)
            {
                try
                {
                    //以下方法针对有窗体显示的进程才有效 
                    switch (m.Msg)
                    {
    
                        case WM_COPYDATA:
                            COPYDATASTRUCT cds = new COPYDATASTRUCT();
                            Type t = cds.GetType();
                            cds = (COPYDATASTRUCT)m.GetLParam(t);
                            string strResult = cds.dwData.ToString() + ":" + cds.lpData;
    
                            //根据 strResult 的内容来做出相应的动作
                  //doSomethings
    break; default: base.DefWndProc(ref m); break; } } catch(Exception ex) { ShowLogInfo(ex.Message); } }
  • 相关阅读:
    Visual Studio使用技巧
    排颜色问题——数组 leetcode lintcode
    【简洁】微信为何总令人感觉如此简洁、?(一)
    字符串通信协议解析函数
    我所改造的JSocket适用于任何DELPHI版本
    缓存和字符串相互转换
    TcxDBTreeList导出EXCEL
    TcxGrid导出EXCEL
    TdxAlertWindowManager右下角HINT显示控件
    好用的编辑框布局控件TdxLayoutControl
  • 原文地址:https://www.cnblogs.com/lpq21314/p/9512730.html
Copyright © 2011-2022 走看看