<strike id="rrvnz"></strike>

    <noframes id="rrvnz">
    <noframes id="rrvnz"><span id="rrvnz"><pre id="rrvnz"></pre></span><address id="rrvnz"></address>
    <address id="rrvnz"><nobr id="rrvnz"></nobr></address><noframes id="rrvnz">
      <em id="rrvnz"></em>

        首 頁IT知識庫翔宇問吧收藏本站
        當前位置:翔宇亭IT樂園IT知識庫C#專區高級應用

        C#應用程序之間相互通信的方法

        減小字體 增大字體 作者:佚名  來源:51csharp.com  發布時間:2014-10-30 17:29:16

        有時,我們需要兩個應用程序之間發送消息,本文就轉載了一篇文章介紹了實現此功能的方法。

        注意這里發送消息的函數:public static void SendMessage(string destProcessName, int msgID, string strMsg),只能發送一個msgID和一個strMsg, 接收方只接收了strMsg,我的項目中已經夠用了,你如果需要讀msgID,還需要改一下。客戶端代碼請參考csdn上的原文自己寫吧。

        進程之間通訊的幾種方法:

        在Windows程序中,各個進程之間常常需要交換數據,進行數據通訊。常用的方法有

        (1)使用內存映射文件

        (2)通過共享內存DLL共享內存

        (3)使用SendMessage向另一進程發送WM_COPYDATA消息

        比起前兩種的復雜實現來,WM_COPYDATA消息無疑是一種經濟實惠的一種方法.

        WM_COPYDATA消息的主要目的是允許在進程間傳遞只讀數據。Windows在通過WM_COPYDATA消息傳遞期間,不提供繼承同步方式。

        SDK文檔推薦用戶使用SendMessage函數,接受方在數據拷貝完成前不返回,這樣發送方就不可能刪除和修改數據:

        這個函數的原型及其要用到的結構如下:

        SendMessage(hwnd, WM_COPYDATA, wParam, lParam);

        其中: WM_COPYDATA對應的十六進制數為0x004A

        wParam設置為包含數據的窗口的句柄。

        lParam指向一個COPYDATASTRUCT的結構:

        typedef struct tagCOPYDATASTRUCT
        {
           DWORD dwData; //用戶定義數據
           DWORD cbData; //數據大小
           PVOID lpData; //指向數據的指針
        } COPYDATASTRUCT;

        該結構用來定義用戶數據。

        具體過程如下:

        首先,在發送方,用FindWindow找到接受方的句柄,然后向接受方發送WM_COPYDATA消息。

        接受方在DefWndProc事件中處理這條消息。由于中文編碼是兩個字節, 所以傳遞中文時候字節長度要搞清楚。

        protected override void DefWndProc(ref System.Windows.Forms.Message m) {
          switch(m.Msg) {
            case WinMessageUtil.WM_COPYDATA:
              string str = WinMessageUtil.ReceiveMessage(ref m);
              break;
            default:
              break;
           }
          base.DefWndProc(ref m);
        }

        using System;
        using System.Runtime.InteropServices;
        using System.Diagnostics;

        namespace Speeding.Util
        {
            //WM_COPYDATA消息所要求的數據結構
            public struct CopyDataStruct
            {
                public IntPtr dwData; //這里注意,一定要用IntPtr網上好多別的用的int會出錯
                public int cbData;
                [MarshalAs(UnmanagedType.LPStr)]
                public string lpData;
            }

            /// <summary>
            /// 本類封裝了一些進程間通訊的細節
            /// </summary>
            public class WinMessageUtil
            {
                public const int WM_COPYDATA = 0x004A;
                //通過窗口的標題來查找窗口的句柄
                [DllImport("User32.dll",EntryPoint="FindWindow")]
                private static extern int FindWindow(string lpClassName, string lpWindowName);
                //在DLL庫中的發送消息函數
                [DllImport("User32.dll",EntryPoint="SendMessage")]
                private static extern int SendMessage
                (
                    int hWnd, // 目標窗口的句柄
                    int Msg, // 在這里是WM_COPYDATA
                    int wParam, // 第一個消息參數
                    ref CopyDataStruct lParam // 第二個消息參數
                );

                /// <summary>
                /// 發送消息,只能傳遞一個自定義的消息ID和消息字符串,想傳一個結構,但沒成功
                /// </summary>
                /// <param name="destProcessName">目標進程名稱,如果有多個,則給每個都發送</param>
                /// <param name="msgID">自定義數據,可以通過這個來決定如何解析下面的strMsg</param>
                /// <param name="strMsg">傳遞的消息,是一個字符串</param>
                public static void SendMessage(string destProcessName, int msgID, string strMsg)
                {
                    if(strMsg == null) return;
                    //按進程名稱查找,同名稱的進程可能有許多,所以返回的是一個數組
                    Process []foundProcess = Process.GetProcessesByName(destProcessName);
                    foreach(Process p in foundProcess)
                    {
                        int toWindowHandler = p.MainWindowHandle.ToInt32();
                        if(toWindowHandler != 0)
                        {
                           CopyDataStruct cds;
                           cds.dwData = (IntPtr) msgID; //這里可以傳入一些自定義的數據,但只能是4字節整數
                           cds.lpData = strMsg; //消息字符串
                           cds.cbData = System.Text.Encoding.Default.GetBytes(strMsg).Length + 1; //注意,這里的長度是按字節來算的
                          //發送方的窗口的句柄, 由于本系統中的接收方不關心是該消息是從哪個窗口發出的,所以就直接填0了
                          int fromWindowHandler = 0;
                          SendMessage(toWindowHandler, WM_COPYDATA, fromWindowHandler, ref cds);
                        }
                      }
                  }
                  /// <summary>
                  /// 接收消息,得到消息字符串
                  /// </summary>
                  /// <param name="m">System.Windows.Forms.Message m</param>
                  /// <returns>接收到的消息字符串</returns>
                  public static string ReceiveMessage(ref System.Windows.Forms.Message m)
                  {
                    CopyDataStruct cds = (CopyDataStruct) m.GetLParam(typeof(CopyDataStruct));
                    return cds.lpData;
                }
            }
        }

        轉載于:http://www.51csharp.com/WinForm/winform_933.html

        Tags:C#

        知識評論評論內容只代表網友觀點,與本站立場無關!

           評論摘要(共 0 條,得分 0 分,平均 0 分) 查看完整評論

        用戶名: 查看更多評論

        分 值:100分 85分 70分 55分 40分 25分 10分 1分

        內 容:

                    請注意用語文明且合法,不要發布帶有攻擊性、侮辱性的言論,謝謝合作!

                 通知管理員 驗證碼:

        關于本站 | 網站幫助 | 廣告合作 | 網站聲明 | 友情連接 | 網站地圖 | 用戶守則 | 聯系我們
        本站部分內容來自互聯網,如有侵權,請來信告之,謝謝!
        Copyright © 2007-2019 biye5u.com. All Rights Reserved.
        網站備案號:黑ICP備13005378號-3
        特黄特色三级在线观看 - 视频 - 在线观看 - 影视资讯 -心晴网