2010-06-22 67 views
2

我正在使用C#中的一個應用程序,它需要將消息發送到C++應用程序。將C#字符串轉換爲長指針

我進口

[DllImport("user32.dll")] 
     public static extern IntPtr SendMessage(
       int hWnd,  // handle to destination window 
       uint Msg,  // message 
       IntPtr wParam, // first message parameter 
       IntPtr lParam // second message parameter 
      ); 

,但現在,我的問題是,我需要過時字符串wParam和lParam。我嘗試了不安全的代碼,但似乎字符串並不像其他變量那樣工作。我怎樣才能做到這一點?謝謝。

+0

我相信'MarshalAs'屬性是有序的。 – ChaosPandion 2010-06-22 15:13:03

回答

-2

我們結束了使用「WmCpyDta_d.dll」來處理所有這些。

+1

雖然這解決了您的問題,這是一種解決方法,不應該是您接受的解決方案。 – DanM7 2012-10-17 13:50:57

0

傳遞字符串的地址將涉及不安全代碼, 因爲Win32 API調用期望地址(在C/C++天然envrion)。你發送的什麼窗口消息需要wParam或lParam中的字符串?

+0

自定義消息。而我無法通過字符串的地址。它只是不想構建它。 – Wildhorn 2010-06-22 15:14:11

11

該聲明是錯誤的,wParam和lParam參數是IntPtr,不長。

由於您嘗試發送字符串,因此會出現複雜情況。如果目標窗口是Unicode啓用或不啓用,那麼重要。有兩個版本的SendMessage,SendMessageA()和SendMessageW()。如果程序過期並使用8位字符串而不是UTF-16編碼字符串,則需要使用前者。

你可以通過使用Spy ++找到。使用取景器工具選擇應用程序的窗口。在General屬性選項卡中,您會看到「Window proc」。它會說(Unicode)該窗口是否啓用了Unicode。如果你沒有看到它,那麼字符串必須被轉換爲8位字符。

要生成需要傳遞的字符串指針,可以使用Marshal.StringToHGlobalAnsi或StringToHGlobalUni(分別爲8位和Unicode)。然而,您可以玩一些技巧讓P/Invoke編組人員爲您翻譯字符串。在通話結束後,您不必麻煩地取出字符串,這讓您省卻麻煩。對於ANSI版本,你可以宣佈這樣的API函數:

[DllImport("user32.dll", CharSet = CharSet.Ansi, EntryPoint = "SendMessageA", ExactSpelling = true)] 
    private static extern IntPtr SendMessageStrings(IntPtr hWnd, int msg, string wParam, string lParam); 

和Unicode版本是這樣的:

[DllImport("user32.dll", CharSet = CharSet.Unicode, EntryPoint = "SendMessageW", ExactSpelling = true)] 
    private static extern IntPtr SendMessageStrings(IntPtr hWnd, int msg, string wParam, string lParam); 

最後一點:這是行不通的,是如果該窗口屬於另一個應用程序,你會崩潰它。你傳遞的指針值只在你自己的進程中有效,而不在C++進程中。要解決該問題,您必須在目標進程中分配內存,以便指針有效。這需要OpenProcess獲得進程的句柄,VirtualAllocEx()在目標進程中分配內存,足以存儲字符串WriteProcessMemory以寫入字符串。現在,您可以調用SendMessage(),使用用IntPtr聲明的版本作爲wParam和lParam參數,傳遞從VirtualAllocEx獲得的值。接下來使用VirtualFreeEx()釋放內存和CloseHandle進行清理。或者如果你經常這樣做,下次保持記憶。

很多P/Invoke在那裏出錯。更不用說安全問題了,WriteProcessMemory需要管理員權限,UAC提升是必需的。

+0

關於你的「最後說明」,你有一些代碼示例嗎?因爲我現在很迷茫。是的,目標應用程序是另一個應用程序(就像我說的,它從C#應用程序到C++應用程序) 我有目標應用程序進程,我的問題是將字符串傳遞給它。 – Wildhorn 2010-06-22 17:21:52

+0

我給你的API函數列表很好。這個查詢的第一個命中看起來不錯:http://www.google.com/#hl=zh-CN&source=hp&q=virtualallocex+writeprocessmemory+sendmessage&aq=f&aqi=&aql=&oq=&gs_rfai=CiOebRfIgTNqjIpaWMf_rnOQNAAAAqgQFT9A3RNM&fp=45835207582d5ee7 – 2010-06-22 17:27:17