2010-01-15 483 views
0

我試圖讓2應用程序使用windows消息相互通信。但是,我在分配內存和編組數據期間一直在獲取AccessViolationException(試圖讀取或寫入受保護的內存)。通過win消息在應用程序之間進行通信

有人可以向我解釋什麼是錯的或建議更好的方法嗎? 謝謝。

編輯:使用WM_COPYDATA建議,但現在我有另一個問題 - 其他應用程序沒有收到WM_COPYDATA消息。怎麼了?發送味精

代碼:用於接收MSG(在其他應用程序)

public const int WM_COPYDATA = 0x004A; 
public struct COPYDATASTRUCT 
{ 
    public int dwData; 
    public int cbData; 
    public DATA lpData; 
} 

public struct DATA 
{ 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=50)] 
    public char[] msg1; 
    [MarshalAs(UnmanagedType.ByValArray, SizeConst=50)] 
    public char[] msg2; 
} 

[DllImport("User32.dll")] 
public static extern int SendMessage(int hWnd, int Msg, IntPtr wParam, ref COPYDATASTRUCT lParam); 

private void button1_Click(object sender, EventArgs e) 
{ 
    // data, with null terminated strings 
    COPYDATASTRUCT cds = new COPYDATASTRUCT(); 
    cds.lpData.msg1 = textBox2.Text.PadRight(50, '\0').ToCharArray(); 
    cds.lpData.msg2 = textBox3.Text.PadRight(50, '\0').ToCharArray(); 
    cds.cbData = Marshal.SizeOf(cds.lpData); 
    int result = SendMessage(hwnd, WM_COPYDATA, System.Diagnostics.Process.GetCurrentProcess().MainWindowHandle, ref cds); // winAPI 

} 

代碼:

protected override void WndProc(ref Message m) 
{ 
    if (m.Msg == WM_COPYDATA) 
    { 
     // doesn't get into this part 

     COPYDATASTRUCT cds = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT)); 
     .... 
    } 
    base.WndProc(ref m); 
} 
+0

除了'Convert.ToChar(0x0)',你可以編寫'「\ 0」'。 – SLaks 2010-01-15 03:56:36

+0

在切換到「WM_COPYDATA」之前,其他應用程序是否收到消息? – SLaks 2010-01-15 14:23:54

回答

2

Windows(和其他現代操作系統)中的指針是與進程相關的。您正在發送指向源進程虛擬內存中地址的指針。在目標進程中,這個相同的虛擬內存位置可能不會被映射,如果它被映射,它將會完全不同。

進程之間複製數據,使用WM_COPYDATA消息和Windows操作系統COPYDATASTRUCT。操作系統提供了這些特殊處理:它在進程之間複製引用數據,併爲目標進程提供一個指向目標進程內存空間中複製數據的指針。

另外,您的Marshal.StructureToPtr調用看起來不正確。你的結構體包含兩個指針(因爲char []是一個引用類型),所以你要將兩個指針複製到你的HGLOBAL中,而不是字節數組的內容。您可能能夠使用MarshalAsAttribute(UnmanagedType.ByValArray)來解決這個問題,但在這種情況下您需要添加大小信息。更簡單的解決方案可能是使用Marshal.Copy方法將數組複製到非託管內存中。

最後,如果您可以控制應用程序,並且可以使用.NET 3.0或以上,考慮託管WCF服務和發送數據的方式。您可能會發現比使用Windows消息更容易,因爲它會爲您處理數據的序列化和反序列化 - 但我意識到這可能不適合您,或者您可能已經排除了它。

+0

我使用的是2.0框架,所以WCF不適合我。 – ahbird 2010-01-15 08:00:45

0

回答您編輯的問題:

您確定您擁有正確的HWND嗎?

用狙++,以確保該HWND是正確的,並檢查間諜++是否看見這條消息。

確保您在這兩個應用正確定義WM_COPYDATA不變。

相關問題