Pass a message to another exe from exe C #

I have two executable programs, C # console programs. From one I need to tell the second exe to do something? How can i do this? i was looking at

(Remotable.CommonAssembly)Activator.GetObject(typeof(Remotable.CommonAssembly)

but from here I can call the CommonAssembly method (referenced by the dll) and not the exe one.

+4
source share
5 answers

For simple scenarios, a simple old Windows event is enough - the program expects it to be asked to do something.

Create a thread in a waiting program, waiting for an event.

 //Program 1 EventWaitHandle evt = OpenOrCreateEvent("Global\\MyEvent"); evt.WaitOne(); // this thread will block waiting without wasting CPU cycles, // it will be be signaled from the kernel // when the event is set DoStuff(); //Program 2 EventWaitHandle evt = OpenOrCreateEvent("Global\\MyEvent"); evt.Set(); 

Take a look at the classes EventWaitHandle, ManualResetEvent, AutoResetEvent.

  • Think about which program is going to create an event - you can try to open an event from both programs if it does not exist, than create it.
  • The prefix of the event name is 'Global \', if one of the programs is a service (and / or works in another session / user). Otherwise, it will not work on Vista or later.
  • When creating an event, you may need to set security attributes so that it can be opened from other processes from other sessions.

Advanced IPC mechanisms, such as WCF, Remoting, DCOM, CORBA, etc., may be better if you have a more complex communication protocol with various actions for starting, returning values, etc. For simple cases (a pair) of window events would be enough.

Note If you need to transfer data between your processes, consider memory mapped files. The "official" .NET classes for them will be available with .NET 4.0, currently you can use http://github.com/tomasr/filemap/tree/master

+5
source

Look at WCF for interprocess communication in .NET. There are many protocols available for single-threaded or remote communications. For the same machine, I would recommend checking named pipes or .NET TCP bindings.

There is a small learning curve for WCF, but there are many tutorials, and this is definitely worth exploring.

+3
source
+2
source

That should do the trick for you ...

[code]

 using System; using System.Collections.Generic; using System.Text; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.InteropServices; using System.Diagnostics; namespace TestApp { public static class Messenger { public const uint WM_USER = 0x0400; public const int MyMessage = 0x00000001;; [DllImport("User32.dll")] private static extern int RegisterWindowMessage(string lpString); [DllImport("User32.dll", EntryPoint = "FindWindow")] internal static extern IntPtr FindWindow(String lpClassName, String lpWindowName); //For use with WM_COPYDATA and COPYDATASTRUCT [DllImport("User32.dll", EntryPoint = "SendMessage")] internal static extern int SendMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam); //For use with WM_COPYDATA and COPYDATASTRUCT [DllImport("User32.dll", EntryPoint = "PostMessage")] internal static extern int PostMessage(int hWnd, int Msg, int wParam, ref COPYDATASTRUCT lParam); [DllImport("User32.dll", EntryPoint = "SendMessage")] internal static extern uint SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, int lParam); [DllImport("User32.dll", EntryPoint = "PostMessage")] internal static extern int PostMessage(int hWnd, int Msg, int wParam, int lParam); [DllImport("User32.dll", EntryPoint = "SetForegroundWindow")] internal static extern bool SetForegroundWindow(int hWnd); //Used for WM_COPYDATA for string messages public struct COPYDATASTRUCT { public IntPtr dwData; public int cbData; [MarshalAs(UnmanagedType.LPStr)] public string lpData; } internal static int sendWindowsStringMessage(int hWnd, int wParam, string msg) { int result = 0; if (hWnd > 0) { byte[] sarr = System.Text.Encoding.Default.GetBytes(msg); int len = sarr.Length; COPYDATASTRUCT cds; cds.dwData = (IntPtr)100; cds.lpData = msg; cds.cbData = len + 1; result = SendMessage(hWnd, (int)WM_USER, wParam, ref cds); } return result; } internal static uint sendWindowsMessage(IntPtr hWnd, uint Msg, IntPtr wParam, int lParam) { uint result = 0; if (hWnd != IntPtr.Zero) { result = SendMessage(hWnd, Msg, wParam, lParam); } return result; } internal static IntPtr getWindowId(string className, string windowName) { return FindWindow(className, windowName); } } 

}

In your calling method:

 uint result = 0; IntPtr hWnd = Messenger.getWindowId(null, "MyOtherApp-Window_Title"); result = Messenger.sendWindowsMessage(hWnd, Messenger.WM_USER, Handle, Messenger.MyMessage); 

[/code]

+2
source

You can consider IPC. NamedPipeClientStream and NamedPipeServerStream are pretty simple. Here is an example where IPC is used to pass command line arguments from one application instance to another. This is not quite what you want to do, but pretty close.

+1
source

Source: https://habr.com/ru/post/1285857/


All Articles