91av视频/亚洲h视频/操亚洲美女/外国一级黄色毛片 - 国产三级三级三级三级

  • 大小: 0.05M
    文件類型: .rar
    金幣: 1
    下載: 0 次
    發布日期: 2020-12-26
  • 語言: C#
  • 標簽: 進程??實例??C#??通訊??

資源簡介

在.NET中基于Windows消息的IPC實現
一、什么是IPC
IPC(Inter process Communication)就是“進程間通訊”。我們都知道,在windows系統中,各個應用程序(進程)之間常常需要交換、傳遞數據,這就要解決進程間的數據通信問題。在最初的16位Windows3.x系統中,所有Windows應用程序共享單一地址,任何進程都能夠對這一共享地址空間的數據進行讀寫操作。
隨著Windwos98、Windows NT、Windows2000等32位的操作系統的出現,每個進程都有自己的地址空間,一個Windows進程不能存取另一個進程的私有數據,也就是說,雖然兩個進程可以用具有相同值的指針尋址,但所讀寫的只是它們各自的數據,這樣就減少了進程之間的相互干擾。
二、如何實現IPC
那么在windows當前系統下,如何實現進程通訊呢?其實有很多方法,如:
1、    剪貼板Clipboard
2、    DDE(動態數據交換)
3、    內存映像
4、    消息管道
5、    郵件槽
6、    Socket
7、    RPC
8、    串行/并行通信(Serial/Parallel Communication)
9、    COM/DCOM
10、Windows消息
三、基于Windows消息的IPC
現在讓我們進入今天我們要講的主題:“基于Windows消息的IPC實現”。
在這里,我假定大家對Windows消息機制都有很好的理解,所以我就不在這上面費太多的墨水了。我們直接看看Windows消息是怎么樣實現進程間通訊的。我們首先看看Windows的消息常數:
WM_COPYDATA=0x004A//  當一個應用程序傳遞數據給另一個應用程序時發送此消息。
這就是我們要的。下面我們來看看如何利用它來實現IPC。
讓我們先看看幾個API函數,沒有它們,我們沒有辦法將數據發送出去。
1、 PostMessage 
函數功能:該函數將一個消息放入(寄送)到與指定窗口創建的線程相聯系消息隊列里,不等待線程處理消息就返回。消息隊列里的消息通過調用GetMessage和PeekMessage取得。
函數原型:B00L PostMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM lParam);
參數
hWnd:其窗口程序接收消息的窗口的句柄。可取有特定含義的兩個值:
HWND.BROADCAST:消息被寄送到系統的所有頂層窗口,包括無效或不可見的非自身擁有的窗口、被覆蓋的窗口和彈出式窗口。消息不被寄送到子窗口。
NULL:此函數的操作和調用參數dwThread設置為當前線程的標識符PostThreadMessage函數一樣。
Msg:指定被寄送的消息。
wParam:指定附加的消息特定的信息。
IParam:指定附加的消息特定的信息。
返回值:如果函數調用成功,返回非零值:如果函數調用失敗,返回值是零。若想獲得更多的錯誤信息,請調用GetLastError函數。
2、 SendMessage 
函數功能:該函數將指定的消息發送到一個或多個窗口。此函數為指定的窗口調用窗口程序,直到窗口程序處理完消息再返回。而函數PostMessage不同,將一個消息寄送到一個線程的消息隊列后立即返回。
函數原型:LRESULT SendMessage(HWND hWnd,UINT Msg,WPARAM wParam,LPARAM IParam);
參數:
hWnd:其窗口程序將接收消息的窗口的句柄。如果此參數為HWND_BROADCAST,則消息將被發送到系統中所有頂層窗口,包括無效或不可見的非自身擁有的窗口、被覆蓋的窗口和彈出式窗口,但消息不被發送到子窗口。
Msg:指定被發送的消息。
wParam:指定附加的消息指定信息。
IParam:指定附加的消息指定信息。
返回值:返回值指定消息處理的結果,依賴于所發送的消息。
3、 RegisterWindowMessage
函數功能:RegisterWindowMessage函數定義一個新的窗口消息,該消息保證在整個系統范圍內是唯一的。調用SendMessage或PostMessage函數時可以使用該函數返回的消息值。
函數原型:UINT RegisterWindowMessage(lpsz)
參數:
lpsz指向一個以NULL結束的字符串,該字符串指定待登記的消息。
返回值:若成功地登記了消息,返回值是一個消息標識符。該標識符值的范圍在0XC000到0XFFFF之間,否則,返回值為0。
我們現在在C#中聲明這些API函數:
        [DllImport("user32")]
        
internal static extern int RegisterWindowMessage(string lpString);
        [DllImport(
"user32")]
        
internal static extern int PostMessage(IntPtr hWnd, int Msg, int wParam, int lParam);
        [DllImport(
"user32")]
        
internal static extern int PostMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);
        [DllImport(
"user32")]
        
internal static extern int SendMessage(IntPtr hWnd, int Msg, IntPtr wParam, ref COPYDATASTRUCT lParam);
然后定義一些我們需要的常數:
                internal const int WM_COPYDATA = 0x004A//當一個應用程序傳遞數據給另一個應用程序時發送此消息
        internal const int WM_DESTROY = 0x0002//窗體被銷毀
        internal const int WM_CREATE = 0x0001//應用程序創建一個窗口
        internal const int WM_QUERYENDSESSION = 0x0011//當用戶選擇結束對話框或程序自己調用ExitWindows函數
        internal static readonly IntPtr HWND_BROADCAST = new IntPtr(0xFFFF);
我們還需要一個傳送數據的結構:
    ///<summary>
    
///發送WM_COPYDATA消息的數據結構
  
///</summary>

    internal struct COPYDATASTRUCT
    
{
        
///<summary>
        
///用戶自定義數據
        
///</summary>

        internal IntPtr dwData;
        
///<summary>
        
///數據長度
        
///</summary>

        internal int cbData;
        
///<summary>
        
///數據首地址指針
        
///</summary>

        internal IntPtr lpData;
    }

現在我們來看看具體如何實現:
1、 我們首先創建一個類,讓它從Form類繼承,因為我們需要一個窗體,然后對它的消息進行處理:

 

internal class WinMsg : Form

{

        
private string _messageString;

        
private List<IntPtr> _windowList;

        
private int _message;

        
private int _intHandler;

        
private bool _isConnected;

}

 

2、 然后定義構造函數,在構造函數里注冊一個消息通道值,并發出一個廣播通知其它在這個通道的窗口。
        internal WinMsg(string messageString)
        
{
            _messageString 
= messageString;
            _isConnected 
= false;
            _intHandler 
= Handle.ToInt32();
            _windowList 
= new List<IntPtr>();
            _message 
= Win32.RegisterWindowMessage(_messageString);//注冊一個消息通道
            int errCode = Win32.PostMessage(Win32.HWND_BROADCAST, _message, Win32.CONNECTION, _intHandler);//向此通道內所有的窗口廣播自己的句柄
            if (errCode == 0)
            
{
                
throw new Win32Exception(errCode);//發生錯誤,拋出異常
            }

            
else
            
{
                _isConnected 
= true;
            }

        }
3、 重寫基類的WndProc函數,處理接收到的消息:
        protected override void WndProc(ref Message m)
        
{
            
if (m.Msg == _message)//接收到廣播消息,進行處理
            {
                
int LParam = m.LParam.ToInt32();
                
int WParam = m.WParam.ToInt32();
                
if (LParam != 0 && LParam != _intHandler)
                
{
                    
if (WParam == Win32.DISCONNECTION)
                    
{
                        _windowList.Remove(m.WParam);
//將對方窗口的句柄從列表中刪除
                    }

                    
else
                    
{
                        
if (WParam==Win32.CONNECTION)
                        
{
                            Win32.PostMessage(m.LParam, _message, Win32.REVERSION, _intHandler);
                        }

                        _windowList.Add(m.LParam);
//將對方窗口的句柄存入列表中
                    }

                }

                
return;
            }

            
switch (m.Msg)
            
{
                
case Win32.WM_COPYDATA://接收到其它窗口發送過來的數據
                    {
                        COPYDATASTRUCT data 
= new COPYDATASTRUCT();
                        data 
= (COPYDATASTRUCT)m.GetLParam(data.GetType());
                        
byte[] message = new byte[data.cbData];
                        Marshal.Copy(data.lpData, message, 
0, data.cbData);//從非托管內存中將數據復制到我們的byte數組中。
                        Anyzler(m.WParam, message);//在這里處理接收到的數據。
                    }

                    
break;
                
case Win32.WM_DESTROY:
                
case Win32.WM_QUERYENDSESSION://窗口被關閉,向其它窗口廣播通知從隊列中刪除自己
                    Win32.PostMessage(Win32.HWND_BROADCAST, _message, Win32.DISCONNECTION, _intHandler);
                    
base.WndProc(ref m);//調用基類的消息處理函數。
                    break;
                
default:
                    
base.WndProc(ref m); //調用基類的消息處理函數。
                    break;
            }

        }
4、 定義發送消息的函數:
        internal void Send(byte[] message)
        
{
            
if (_isConnected)
            
{
                
int length = message.Length;
                IntPtr ptr 
= Marshal.AllocHGlobal(length);//申請一塊非托管內存
                Marshal.Copy(message, 0, ptr, length);//將要發送的數據封送到非托管內存
                COPYDATASTRUCT data = new COPYDATASTRUCT();
                data.dwData 
= IntPtr.Zero;//這里可以隨意定義。
                data.cbData = length;//傳遞要發送的數據的長度
                data.lpData = ptr;//傳遞要發送的數據的地址指針
                
//向其它所有窗口發送數據,這里不能發廣播消息。必須一個一個發送。
                foreach (IntPtr window in _windowList)
                
{
                    Win32.SendMessage(window, Win32.WM_COPYDATA, 
this.Handle, ref data);
                }

                Marshal.FreeHGlobal(ptr);
//釋放這塊非托管內存,這行一定要寫上,不然會內存泄漏。
            }

        }
好了,主要代碼就是這些了!

資源截圖

代碼片段和文件信息

using?System;
using?System.Collections.Generic;
using?System.ComponentModel;
using?System.Data;
using?System.Drawing;
using?System.Text;
using?System.Windows.Forms;
using?System.Runtime.InteropServices;
using?System.Threading;

namespace?WindowsApplication3
{
????public?partial?class?Form1?:?Form
????{
????????MyWindowsMessage?msgData;
????????public?Form1()
????????{
????????????InitializeComponent();
????????}

????????protected?override?void?onload(EventArgs?e)
????????{
????????????msgData?=?new?MyWindowsMessage(“testProject“);
????????????msgData.Parent?=?this;
????????????msgData.StartMessage();
????????}

?????????private?void?button1_Click(object?sender?EventArgs?e)
????????{
????????????msgData.SendMessage(Encoding.Default.GetBytes(textBox1.Text));
?

?屬性????????????大小?????日期????時間???名稱
-----------?---------??----------?-----??----

?????文件??????24576??2007-04-28?13:08??WindowsApplication3\WindowsApplication3\bin\Debug\WindowsApplication3.exe

?????文件??????34304??2007-04-28?13:08??WindowsApplication3\WindowsApplication3\bin\Debug\WindowsApplication3.pdb

?????文件???????5632??2005-09-23?06:56??WindowsApplication3\WindowsApplication3\bin\Debug\WindowsApplication3.vshost.exe

?????文件???????1656??2007-04-28?13:08??WindowsApplication3\WindowsApplication3\Form1.cs

?????文件???????4799??2007-04-28?13:08??WindowsApplication3\WindowsApplication3\Form1.Designer.cs

?????文件???????5814??2007-04-28?13:08??WindowsApplication3\WindowsApplication3\Form1.resx

?????文件????????842??2007-04-28?13:08??WindowsApplication3\WindowsApplication3\obj\Debug\WindowsApplication3.csproj.GenerateResource.Cache

?????文件??????24576??2007-04-28?13:08??WindowsApplication3\WindowsApplication3\obj\Debug\WindowsApplication3.exe

?????文件????????180??2007-04-28?13:08??WindowsApplication3\WindowsApplication3\obj\Debug\WindowsApplication3.Form1.resources

?????文件??????34304??2007-04-28?13:08??WindowsApplication3\WindowsApplication3\obj\Debug\WindowsApplication3.pdb

?????文件????????180??2007-04-28?13:01??WindowsApplication3\WindowsApplication3\obj\Debug\WindowsApplication3.Properties.Resources.resources

?????文件????????352??2007-04-28?13:09??WindowsApplication3\WindowsApplication3\obj\WindowsApplication3.csproj.FileList.txt

?????文件????????489??2007-04-24?17:21??WindowsApplication3\WindowsApplication3\Program.cs

?????文件???????1308??2007-04-24?17:21??WindowsApplication3\WindowsApplication3\Properties\AssemblyInfo.cs

?????文件???????2865??2007-04-24?17:21??WindowsApplication3\WindowsApplication3\Properties\Resources.Designer.cs

?????文件???????5612??2007-04-24?17:21??WindowsApplication3\WindowsApplication3\Properties\Resources.resx

?????文件???????1102??2007-04-24?17:21??WindowsApplication3\WindowsApplication3\Properties\Settings.Designer.cs

?????文件????????249??2007-04-24?17:21??WindowsApplication3\WindowsApplication3\Properties\Settings.settings

?????文件???????3335??2007-04-28?13:01??WindowsApplication3\WindowsApplication3\WindowsApplication3.csproj

?????文件???????9053??2007-04-28?13:28??WindowsApplication3\WindowsApplication3\WindowsMessage.cs

?????文件????????946??2007-04-24?17:21??WindowsApplication3\WindowsApplication3.sln

????..A..H.?????74752??2007-04-28?13:53??WindowsApplication3\WindowsApplication3.suo

?????目錄??????????0??2007-04-25?11:41??WindowsApplication3\WindowsApplication3\obj\Debug\Refactor

?????目錄??????????0??2007-04-24?17:21??WindowsApplication3\WindowsApplication3\obj\Debug\TempPE

?????目錄??????????0??2007-04-28?13:01??WindowsApplication3\WindowsApplication3\bin\Debug

?????目錄??????????0??2007-04-28?13:08??WindowsApplication3\WindowsApplication3\obj\Debug

?????目錄??????????0??2007-04-28?10:00??WindowsApplication3\WindowsApplication3\bin

?????目錄??????????0??2007-04-26?17:16??WindowsApplication3\WindowsApplication3\obj

?????目錄??????????0??2007-04-24?17:21??WindowsApplication3\WindowsApplication3\Properties

?????目錄??????????0??2007-04-28?13:28??WindowsApplication3\WindowsApplication3

............此處省略4個文件信息

評論

共有 條評論