通过 SendMessage 的 C# 应用程序间通信

C# Inter-Application Communications through SendMessage

所以在找到一个合适的方法来为我的不同进程进行通信的方式遇到很多问题之后,我拼凑了这个:

public const uint HWND_BROADCAST = 0xffff;
[DllImport( "user32" )]
public static extern bool SendMessage(IntPtr hwnd, IntPtr msg, IntPtr wparam, IntPtr lparam);
[DllImport( "user32" )]
public static extern int RegisterWindowMessage(string message);
public static readonly uint WM_COPYDATA = (uint)RegisterWindowMessage( "WM_COPYDATA_DESKTOP_TODOLIST_9234892348932GIBBERISH" );

使用方法如下:

public static void SendMessage(string Message) {
SendMessage( (IntPtr)HWND_BROADCAST, (IntPtr)WM_COPYDATA, (IntPtr)Rawify( ref Message ), (IntPtr)Message.Length );
}

// Preparing the message for pointer-sending
public static IntPtr Rawify(ref string target) {
char[] CHARS = target.ToCharArray();

// Copy string to raw memory block of bytes
int count = target.Length;
IntPtr P = Marshal.AllocHGlobal( 2 * count );
for (int I = 0; I < count; I++) {    Marshal.WriteInt16( (IntPtr)((int)P + I * 2), target[I] );    }

return P;
}

public static string Cook(IntPtr target, IntPtr length) {
int count = (int)length;
char[] CHARS = new char[count];

// Copy raw memory to char array->string
for (int I = 0; I < count; I++) {    CHARS[I] = (char)Marshal.ReadInt16( (IntPtr)((int)target + I * 2) );    }

return new string( CHARS );
}
}

在接收端

// Receiver for alternate applications
protected override void WndProc(ref Message m) {
if (m.Msg == Native.Messaging.WM_COPYDATA) { MessageBox.Show( "[" + Native.Messaging.Cook( m.WParam, m.LParam ) + "]" ); }
base.WndProc( ref m ); // Default handling
}

现在,一切都很好,我已经彻底测试过了;

我从 Runtime.InteropServices 那里借用了 SendMessage。 消息发送成功。 但是,它仅限于两个可怜的 IntPtr。

所以我决定最好的办法是发送一个指向一些非托管内存的指针,以及该内存的大小。

发送成功,但是在两个不同的程序实例中,指针显然没有指向同一个地方。看起来 Marshal.AllocHGlobal 的 IntPtr 是一些仅与当前程序相关的任意本地指针,因此在某些时候为 read/write 访问冲突、一些随机空值或一些随机其他字符提供了异常我什至从某处随机抽取了一个 "l32.dll" 字符串。阴森森的!

我只是想知道如何跨两个不同的应用程序获取指向相同数据的指针。我什至不知道从哪里开始寻找这个答案,因此我为什么要在这里问。

有没有办法通过 Marshals 获取该指针,或者我需要其他东西。 我可以弄清楚细节,我只需要知道一些指针,如果在多个程序中使用,它指向 相同的数据

或者,如果我正在做的事情非常可怕并且是个坏主意,我希望被告知替代方案,只要它们不是: 命名管道, RPC, 内存映射, 文件, 互斥;因为,出于某种原因,我在 .NET 2.0 中工作,而这些在 .NET 2.0 中不可用;并且 Mutex 不传输数据;我喜欢我的硬盘漂亮、干净、不忙且处于原始状态。

再次提醒:目标是在同一程序的多个实例之间或其他可能的其他实例之间传递任何类型和任何大小的数据(我可以接受一些限制)程序,即它自己的 ApplicationDomain 中的 .EXE 等

忘了说,这必须在 .NET 2.0 中,我只需要一个指向多个应用程序之间相同数据的某种指针。

哇!为什么不使用 WCF 通过 IPC 在进程之间进行通信?

http://tech.pro/tutorial/855/wcf-tutorial-basic-interprocess-communication

http://dotnet-experience.blogspot.com.es/2012/02/inter-process-duplex-communication-with.html

我猜你要么需要在源进程上 OpenHandle 并从那里 ReadProcessMemory (因为你广播的内存地址是应用程序的本地地址),或者使用memory-mapped files 或共享内存 space。无论哪种方式,您都在深入研究 Win32 P/Invoke 领域,因为两者都无法在 .NET 2.0 上完全托管。

编辑:您似乎编辑了您的问题以将这些作为可行的候选者删除。您要求 IPC 方法,同时排除所有 IPC 方法(没有理由)。