0

I need to pass an object of a class from one program to another.

This is the class I need to pass;

[StructLayout( LayoutKind.Sequential, CharSet = CharSet.Ansi )]
public class MessageContainer
{
    public bool DescFirst { get; set; }      
    [MarshalAs( UnmanagedType.ByValTStr, SizeConst = 200 )]
    public string Data;
    public decimal PriceMin { get; set; }
    public int Hidden { get; set; }

    public MessageContainer()
    {
        DescFirst = true;
    }
}

CopyDataStruct Class;

public struct CopyDataStruct : IDisposable
        {
            public IntPtr dwData;
            public int cbData;
            public IntPtr lpData;

            public void Dispose()
            {
                if (this.lpData != IntPtr.Zero)
                {
                    LocalFree(this.lpData);
                    this.lpData = IntPtr.Zero;
                }
            }
        }

How I send object;

    {
    int hwnd = -1;
    IntPtr handle = IntPtr.Zero;

    foreach (Process proc in Process.GetProcesses())
    {
        if (proc.MainWindowTitle.StartsWith("MyApp"))
        {
            handle = proc.MainWindowHandle;
        }
    }

    if (handle != IntPtr.Zero)
    {       
        Win32.CopyDataStruct cds = new Win32.CopyDataStruct();
        MessageContainer cs = new MessageContainer();
        cs.Data = "Test123";
        cds.DescFirst = true;
        cds.lpData = Marshal.AllocHGlobal(Marshal.SizeOf(cs));
        cs.PriceMin = "1.25";
        cs.Hidden = 0;

        try
        {
            Marshal.StructureToPtr(cs, cds.lpData, false);
            Win32.SendMessage(handle, Win32.WM_COPYDATA, IntPtr.Zero, ref cds);
        }
        finally
        {
            Marshal.FreeHGlobal(cds.lpData);
        }
    }
    else
        MessageBox.Show("Not send");
}

On the other application;

protected override void WndProc(ref Message m)
        {
            switch ( m.Msg )
            {
                case Win32.WM_COPYDATA:

                    Win32.CopyDataStruct cds = (Win32.CopyDataStruct)m.GetLParam(typeof(Win32.CopyDataStruct));

                    // If the size matches
                    if ( cds.cbData == Marshal.SizeOf(typeof(MessageContainer)) )
                    {
                        MessageContainer msg = (MessageContainer)Marshal.PtrToStructure(cds.lpData, typeof(MessageContainer));
                        if ( msg != null )
                        {
                            TextBox1.text = msg.Data;
                        }
                    }
                    break;
                default:
                    // let the base class deal with it
                    base.WndProc(ref m);
                    break;
            }
        }

I get all the data other than "string" data type ("Test123") on target application. Get blank for "Data".

No errors, both applications work. Object get transfered, but on string variables no data.

Please help me on this

Buddhi Dananjaya
  • 643
  • 2
  • 12
  • 32
  • 1
    Huh. That’s how I did IPC 10 years ago. Aren’t there better ways now? Framework functions? Named pipes? Sockets? http://stackoverflow.com/q/56121/1968 – Konrad Rudolph Nov 03 '16 at 10:47
  • Read your link. On the answer of it says ".... Actually there is nothing new in the lower level (tcp, upd, named pipes etc) But WCF simplifies IPC development .... " Seems we are still eating the same case wrapped in a nice paper – Buddhi Dananjaya Nov 03 '16 at 10:55
  • You’re cherry-picking the wrong parts. There *is* tons of new things, in the form of WCF and clrzmq4. Bottom line, don’t use the WinAPI directly for this kind of stuff if you want to avoid the pain. – Konrad Rudolph Nov 03 '16 at 11:58
  • Nothing yells that loud, makes little sense that PriceMin makes it across but Data doesn't. Except for that Dispose() method, it is evil and can only corrupt memory in the receiver. Delete it. Having fields and properties mixed doesn't help you debug this, make them all fields so you can predict the field order and have a shot at debugging it with the Debug > Windows > Memory > Memory1 window. Making sure that both programs use the *exact* same declaration of MessageContainer is entirely up to you, a mismatch is enough to explain the problem. – Hans Passant Nov 03 '16 at 12:44

0 Answers0