Recent

Author Topic: Anyone know the protocol to connect to TSimpleIPCServer from c# client?  (Read 17447 times)

Michael Collier

  • Sr. Member
  • ****
  • Posts: 253
I'd like to try to connect to a lazarus TSimpleIPCServer component from a C# client program but I don't know what the method/protocol would be for that.

I can do IPC client/server in lazarus, and I can do client/server in C# using named pipes but named pipes doesn't seem to be the way to connect to TSimpleIPCServer (or is it??)....

Has anyone here tried it with C# or know more about what TSimpleIPCServer is doing under the hood so maybe I can ask in a C# forum??..

TIA

Leledumbo

  • Hero Member
  • *****
  • Posts: 8114
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #1 on: February 07, 2012, 02:47:35 am »
The documentation doesn't mention the protocol used as well, so I guess this component aren't meant to be used from other languages. You have to dig in the source code to see it.

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #2 on: February 07, 2012, 07:10:27 am »
I seem to recall they use pipes on Windows... there were some troubles getting services/daemons and end user programs to communicate...

As Leledumbo said, you'd probably have to figure it out via code, but I think that if you have interprocess communication facilities, it would really help if they can be used by other languages  :D
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

TurboRascal

  • Hero Member
  • *****
  • Posts: 672
  • "Good sysadmin. Bad programmer."™
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #3 on: February 07, 2012, 03:15:40 pm »
It seems it also uses pipes for communication. You may replicate what the code does from the client source, or perhaps even simpler, just create a wrapper dll...
Regards, ArNy the Turbo Rascal
-
"The secret is to give them what they need, not what they want." - Scotty, STTNG:Relics

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #4 on: October 06, 2012, 04:01:42 am »
@richardalgor: so, if you have an sample C# program with a sample Lazarus TSimpleIPCServer program, that would be very nice.

Thanks,
BigChimp
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

ludob

  • Hero Member
  • *****
  • Posts: 1173
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #5 on: October 06, 2012, 10:04:42 am »
SimpleIPC uses windows messaging to communicate (WM_COPYDATA). Here is a sample C# console program that writes to a FPC IPC server:
Code: [Select]
using System;
using System.Runtime.InteropServices;


namespace ConsoleApplication1
{

    class Program
    {
        [DllImport("user32.dll", SetLastError = true)]
        static extern int FindWindow(string lpClassName, string lpWindowName);
        [DllImport("user32.dll")]
        public static extern int SendMessage(int hWnd, int wMsg, int wParam, ref COPYDATASTRUCT lparam);
        public const int WM_COPYDATA = 0x4A;
        public struct COPYDATASTRUCT
        {
        public IntPtr dwData;
        public int cbData;
        [MarshalAs(UnmanagedType.LPStr)]
        public string lpData;
        }


        static int sendFPCIPCMessage(string ServerID, int MsgType, string msg)
        {
            int hWnd = FindWindow("FPCMsgWindowCls", ServerID);
            Console.WriteLine(hWnd);
            byte[] sarr = System.Text.Encoding.Default.GetBytes(msg);
            int len = sarr.Length;
            COPYDATASTRUCT cds;
            cds.dwData = (IntPtr)MsgType;
            cds.lpData = msg;
            cds.cbData = len + 1;
            return SendMessage(hWnd, WM_COPYDATA, 0, ref cds);
        }
        static void Main(string[] args)
        {
            Console.WriteLine(sendFPCIPCMessage("123", 3, "Hi from C#"));
        }
    }
}
The Console.WriteLine is just for debugging purposes. This is a test program and needs some better error checking to be useful.

To test, create a FPC program with a TSimpleIPCServer and set TSimpleIPCServer.ServerID to '123',  TSimpleIPCServer.Global to true, an OnMessage handler with
Code: [Select]
procedure TForm1.SimpleIPCServer1Message(Sender: TObject);
begin
  ShowMessage(SimpleIPCServer1.StringMessage);
end;
and start the server. Run the console app and enjoy the popup in the FPC program :)

evoshroom

  • Full Member
  • ***
  • Posts: 157
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #6 on: January 18, 2013, 02:37:24 pm »
Amazingly useful.  Any chance you'd have some code receive to SimpleIPC commands for a non-console visual C# program?
« Last Edit: January 18, 2013, 06:01:13 pm by evoshroom »

evoshroom

  • Full Member
  • ***
  • Posts: 157
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #7 on: January 18, 2013, 06:06:39 pm »
Going to try to implement this and hope it is compatible...*fingers crossed*

http://msdn.microsoft.com/en-us/library/system.runtime.remoting.channels.ipc.ipcserverchannel.aspx

I got your demo working like a dream in my C# project and this is the first time I've even seen C# code.  I'm an OS X developer!

evoshroom

  • Full Member
  • ***
  • Posts: 157
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #8 on: January 18, 2013, 06:55:51 pm »
Actually, looking more into it IpcServerChannel Class is both wrong and overkill.  It receives messages using SOAP.  The Windows version of SimpleIPC uses WM_COPYDATA so something like this http://stackoverflow.com/questions/1633501/receive-wm-copydata-struct-in-wpf-or-console-c-sharp-app or this http://forums.devshed.com/c-programming-42/using-wm-copydata-to-send-message-from-c-to-c-553567.html is more on-track.

evoshroom

  • Full Member
  • ***
  • Posts: 157
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #9 on: January 18, 2013, 10:17:22 pm »
So I tried taking the code here:

http://msdn.microsoft.com/en-us/library/system.windows.forms.nativewindow.aspx

And then I changed:

Code: [Select]
cp.Caption = "Click here";
cp.ClassName = "Button";

to

Code: [Select]
cp.Caption = "321";
cp.ClassName = "FPCMsgWindowCls";

The above class name I gathered both from the working C# code above and from: https://github.com/graemeg/freepascal/blob/master/packages/fcl-process/src/win/simpleipc.inc

Then I replaced the included "protected override void WndProc(ref Message m)" with

Code: [Select]
  public const int WM_COPYDATA = 0x4A;
        public struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cbData;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpData;
        }
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
            case WM_COPYDATA:
                COPYDATASTRUCT mystr = new COPYDATASTRUCT();
                Type mytype = mystr.GetType();
                mystr = (COPYDATASTRUCT)m.GetLParam(mytype);
                MessageBox.Show(mystr.lpData);
                break;
            }
            base.WndProc(ref m);
        }

I also set my SimpleIPCClient in my Lazarus program to ServerID 321 and set it up to connect like normal.  It never connected though.  I'm completely new at C#, so I'm not sure if that is because of my day one C#'s skills or something I missed.  Anyone a bilingual Object Pascal/C# speaker?
« Last Edit: January 18, 2013, 11:52:16 pm by evoshroom »

evoshroom

  • Full Member
  • ***
  • Posts: 157
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #10 on: January 18, 2013, 11:31:52 pm »
Well back to the path of least resistance.  If any C# guru's out there code a SimpleIPCClient-compatible C# implementation toss it in this thread in the future.  In the meantime, a SimpleIPCServer and this code to act as a substitute for a client will work:

Lazarus:
Code: [Select]
var
  aCopyData: TCopyDataStruct;
  hTargetWnd: HWND;
begin
  with aCopyData do
  begin
    dwData := 0;
    cbData := StrLen(PChar('test')) + 1;
    lpData := PChar('test')
  end;
  // Search window by the window title
  hTargetWnd := FindWindowEx(0, 0, nil, PChar('AppTitleBar'));
  if hTargetWnd <> 0 then
    SendMessage(hTargetWnd, WM_COPYDATA, Longint(Handle), Longint(@aCopyData))
  else
    ShowMessage('No Recipient found!');

C#:
Code: [Select]
        protected override void WndProc(ref Message m)
        {
            switch (m.Msg)
            {
                case WM_COPYDATA:
                    COPYDATASTRUCT mystr = new COPYDATASTRUCT();
                    Type mytype = mystr.GetType();
                    mystr = (COPYDATASTRUCT)m.GetLParam(mytype);
                    MessageBox.Show(mystr.lpData);
                    break;
            }
            base.WndProc(ref m);

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #11 on: January 19, 2013, 11:07:55 am »
Looks like you've been busy, evoshroom!

If you're just looking for a GUI version of ludob's console example, I've tried to come up with one (not a C# coder but have some VB.Net experience).
Haven't tested it with a server, but it compiles and runs...
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

evoshroom

  • Full Member
  • ***
  • Posts: 157
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #12 on: January 19, 2013, 02:44:11 pm »
Looks like you've been busy, evoshroom!

If you're just looking for a GUI version of ludob's console example, I've tried to come up with one (not a C# coder but have some VB.Net experience).
Haven't tested it with a server, but it compiles and runs...

Oh, no, I'm not looking for a GUI version of ludob's console example.  I have his console example working in my GUI C# program already.  That only took a few minutes.  However, his example only goes in one direction:

C# program to Lazarus program (TSimpleIPCServer)

I was looking for the other way as well:

Lazarus program (TSimpleIPCClient) to C# program

If you go in the other direction it seemed to me that you need to override the classname of a C# form to be called "FPCMsgWindowCls" and that was where most of the difficulty was.

BigChimp

  • Hero Member
  • *****
  • Posts: 5740
  • Add to the wiki - it's free ;)
    • FPCUp, PaperTiger scanning and other open source projects
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #13 on: January 19, 2013, 02:46:48 pm »
Seems I misunderstood you then.

Having to modify a form (GUI!) class name seems weird though.
Want quicker answers to your questions? Read http://wiki.lazarus.freepascal.org/Lazarus_Faq#What_is_the_correct_way_to_ask_questions_in_the_forum.3F

Open source including papertiger OCR/PDF scanning:
https://bitbucket.org/reiniero

Lazarus trunk+FPC trunk x86, Windows x64 unless otherwise specified

evoshroom

  • Full Member
  • ***
  • Posts: 157
Re: Anyone know the protocol to connect to TSimpleIPCServer from c# client?
« Reply #14 on: January 19, 2013, 03:11:01 pm »
Seems I misunderstood you then.

Having to modify a form (GUI!) class name seems weird though.

From my understanding that's because on Windows TSimpleIPCClient carries an assumption that it is talking to a TSimpleIPCServer.  The ServerID is the Form Title for the FindWindowEx(hwndParent, hwndChildAfter, lpszClass, lpszWindow) and the form class is FPCMsgWindowCls, but I should do some searches in that source I linked for FindWindowEx, as I didn't confirm all of that, it just seemed naturally to follow from some of the assumptions made elsewhere and Windows API calls.