1

So after a lot of problems finding a proper way to make a way for my different processes to communicate, I cobbled together this:

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" );

Which is used in the following way:

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 );
}
}

And on the receiving end

// 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
}

Now, all is peachy and I've tested thoroughly;

What happens is I've borrowed SendMessage from Runtime.InteropServices. The message is sent successfully across. However, it's limited to two pathetic IntPtr's.

So I decided the best thing to do is sent over a pointer to some unmanaged memory, and the size of that memory.

The sending is successful, however in the two different program instances, the pointer, apparently, doesn't point to the same place. It looks like the IntPtr that Marshal.AllocHGlobal is some arbitrary local pointer relevant only the current program, thus giving me exceptions for read/write access violations, or some random nulls, or some random other characters, and at some point I even sampled a random "l32.dll" string from somewhere. Spooky!

I only, and simply want to know how to get a Pointer, that would point to the SAME DATA, across two different applications. I'm so clueless where to even start searching for this answer, hence why I ask here.

Is there a way to get that pointer with Marshals, or I need something else. I can figure out the details, I just need to be let known about some Pointer, that points to the same data if used in multiple programs.

Alternatively, if what I'm doing is grotesquely horrible and a bad idea, I'd like to be informed of alternatives, so long as they are not: Named pipes, RPC, Memorymapped, Files, Mutex; because, for reasons, I'm working in .NET 2.0, and those are not available there; And Mutex doesn't transfer data; And I like my hard disk nice, clean, un-busy and in pristine condition.

Again, Reminder: The goal is to communicate DATA of ANY TYPE and ANY SIZE (I can accept some limits), BETWEEN multiple INSTANCES of the same PROGRAM, or possibly other PROGRAMS, that is an .EXE in its own ApplicationDomain and etc.

Forgot to mention, this has to be in .NET 2.0, and all I need is a POINTER of some kind that points to the SAME DATA between multiple applications.

  • Yeah, ReadProcessMemory requires a lot more data than just two IntPtrs can handle. I'm not necessarily looking for a managed way to do this. I just want some "Global" pointer that's valid inbetween applications, with minimal overhead. Alternatively I can just send multiple SendMessages and synchronize them to do the ReadProcessMemory hax. – Alucard Pawpad Feb 19 '15 at 15:32
  • What I "professionally" need was .NET Remote Method Invocation, which is basically a TCP connection, sending data with HTTP protocol between apps, to do something similar to what i need. I need an offline protocol-less data connection; and the randomization that Windows Programs suffer makes it necessary to pass the pointer to the process and the data. Seems like there's no way to better this. – Alucard Pawpad Feb 20 '15 at 10:22

2 Answers2

1

Wow! Why you don't use WCF to comunicate between process via 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

Oscar
  • 13,594
  • 8
  • 47
  • 75
1

I'm guessing you'd either need to OpenHandle on the source process and ReadProcessMemory from there (since the memory address you're broadcasting is local to the application), or use memory-mapped files or shared memory space. Either way you are digging into Win32 P/Invoke land as neither is available fully managed on .NET 2.0.

Edit: It appears you edited your question to remove these as viable candidates. You're asking for methods of IPC while excluding all methods of IPC (without a reason).

wgraham
  • 1,383
  • 10
  • 16
  • Opening a handle and reading from ReadProcessMemory requires extra stuff, like knowing the source program; and that's too much hassle which I'll only implement if there's no other way. I'm also not necessarily looking for a 'managed' way to do this. – Alucard Pawpad Feb 19 '15 at 15:33
  • Any reason why you're throwing MMF out the window? They aren't necessarily persisted to disk, you have the option to specify a "transient" memory-mapped file when creating it. – wgraham Feb 19 '15 at 15:34
  • Not supported in .NET-2.0. I would've loved to use them, if they were available. They also don't do what I exactly want them to do. – Alucard Pawpad Feb 19 '15 at 15:36
  • You said you're not necessarily looking for a "Managed" way to do this -- so P/Invoke the MMF APIs (starting with [CreateFileMapping](https://msdn.microsoft.com/en-us/library/windows/desktop/aa366537(v=vs.85).aspx)). – wgraham Feb 19 '15 at 15:37
  • As I said, MMF is out of the question. – Alucard Pawpad Feb 19 '15 at 15:40
  • OK. So broadcast a message (using `SendMessage`) containing the source's process ID and the memory offset of the data -- then target applications know where to look for it. As far as data size, just prepend the data length at the first 4 (or 8) bytes of the offset. Edit: what you're doing is a grotesquely horrible and bad idea, however. – wgraham Feb 19 '15 at 15:47