Я пишу новый инструмент для своей организации, который должен общаться через SendMessage с унаследованным инструментом.AccessViolation при вызове Marshal.Copy using user32 SendMessage
Я только что сделал тест приложение, используя код здесь: http://www.c-sharpcorner.com/Blogs/6444/
Я отредактированный код отправки в соответствии своей цели. Но у меня возникают проблемы с получением сообщений в форме «GetMessage». Сообщение проходит, но программа ломается при попытке преобразования данных в строку.
Вот мой код:
Отправить:
[DllImport("user32.dll", CharSet = CharSet.Auto)]
static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, ref COPYDATASTRUCT lParam);
[DllImport("USER32.DLL", CharSet = CharSet.Unicode)]
public static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
private void button1_Click(object sender, EventArgs e)
{
IntPtr hwnd = FindWindow(null, "GetMessage");
if (hwnd != null)
{
string message = textBox1.Text + "-" + System.DateTime.Now.ToString();
COPYDATASTRUCT cds;
cds.dwData = 0;
cds.lpData = (int)Marshal.StringToHGlobalAnsi(message);
cds.cbData = message.Length;
SendMessage(hwnd, (int)WM_COPYDATA, 0, ref cds);
}
}
Recieve:
private const int WM_COPYDATA = 0x4A;
[StructLayout(LayoutKind.Sequential)]
struct COPYDATASTRUCT
{
public int dwData;
public int cbData;
public int lpData;
}
protected override void WndProc(ref Message m)
{
switch (m.Msg)
{
case WM_COPYDATA:
COPYDATASTRUCT CD = (COPYDATASTRUCT)m.GetLParam(typeof(COPYDATASTRUCT));
byte[] B = new byte[CD.cbData];
IntPtr lpData = new IntPtr(CD.lpData);
//string test = Marshal.PtrToStringAuto(lpData, CD.lpData); // this doesn't work either
Marshal.Copy(lpData, B, 0, CD.cbData); // access violation here
string strData = Encoding.Default.GetString(B);
listBox1.Items.Add(strData);
break;
default:
base.WndProc(ref m);
break;
}
}
Ошибка я получаю:
Попытка чтения или записи в защищенную память , Это часто является индикатором , что другая память повреждена.
Я попытался установить строку сообщения в посыле на поле (так что не выходит за рамки), установив «ИНТ WPARAM» аргумент Отправить сообщение на «IntPtr» и использование IntPtr. нулевой вместо 0 в моей SendMessage вызов, и нуль завершения строки, как показано ниже:
cds.lpData = (int)Marshal.StringToHGlobalAnsi(message + '\0');
cds.cbData = (message+'\0').Length;
все еще получаю такую же проблему.
Вы пробовали [Marshal.PtrToStringAnsi] (http://msdn.microsoft.com/en-us/library/vstudio/system.runtime.interopservices.marshal.ptrtostringansi (v = vs.100) .aspx)? –
Ваши объявления ошибочны, этот код не может работать в 64-битном режиме и сбой будет зафиксирован, если вы его попробуете. Получите лучшее от веб-сайта http://pinvoke.net. –