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); } }
  • 相关阅读:
    Power BI 根据用户权限动态生成导航跳转目标
    Power BI Tooltips 增强功能
    Power BI refresh error “could not load file or assembly…provided impersonation level is invalid”
    SQL 错误代码 18456
    如何使用SQL Server Integration Services从多个Excel文件读取数据
    通过表格编辑器将现有表引入Power BI数据流
    Power BI 中动态增长的柱状图
    ambari2.7.3离线安装hdp3.1.0时,ambari-hdp-1.repo中baseurl无值
    ambari 安装 cannot download file mysql-connector-java from http://8080/resource/mysql-connector-java.jar
    洛谷P4180 [BJWC2010]严格次小生成树
  • 原文地址:https://www.cnblogs.com/lpq21314/p/9512730.html
Copyright © 2011-2022 走看看