C# コンソール プログラムを 2 つ実行しています。1つから、2番目のexeに何かをするように指示する必要がありますか? これどうやってするの?私は見た
(Remotable.CommonAssembly)Activator.GetObject(typeof(Remotable.CommonAssembly)
しかし、ここから、exe のメソッドではなく、CommonAssembly(参照された dll) のメソッドを呼び出すことができます。
単純なシナリオでは、単純な古いWindowsイベントで十分です。プログラムは、何かを実行するように通知されるのを待ちます。
イベントを待機する待機中のプログラムにスレッドを生成します。
//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();
EventWaitHandle、ManualResetEvent、AutoResetEventクラスを見てください。
WCF、Remoting、DCOM、CORBAなどの高度なIPCメカニズムは、トリガーや戻り値などのさまざまなアクションを備えたより複雑な通信プロトコルを使用している場合に適しています。単純なケース(カップル)の場合、Windowsイベントで十分です。
注意 プロセス間でデータを転送する必要がある場合は、メモリマップトファイルを検討してください。それらの「公式」.NETクラスは.NET4.0で利用可能になります。現在、http ://github.com/tomasr/filemap/tree/masterを使用できます。
.NETでのプロセス間通信についてはWCFを調べてください。同じマシンまたはリモートマシンの通信に使用できるさまざまなプロトコルがあります。同じマシンの場合、名前付きパイプまたは.NETTCPバインディングを確認することをお勧めします。
WCFにはわずかな学習曲線がありますが、そこにはたくさんのチュートリアルがあり、それは間違いなく学ぶ価値のあるものです。
私はこれにMSMQを頻繁に使用します。
これでうまくいくはずです...
[コード]
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);
}
}
}
呼び出し方法で:
uint result = 0;
IntPtr hWnd = Messenger.getWindowId(null, "MyOtherApp-Window_Title");
result = Messenger.sendWindowsMessage(hWnd, Messenger.WM_USER, Handle, Messenger.MyMessage);
[/コード]
あなたはIPCを検討するかもしれません。 NamedPipeClientStreamとNamedPipeServerStreamは非常に単純です。 以下は、IPC を使用して、アプリケーションのあるインスタンスから別のインスタンスにコマンド ライン引数を渡す例です。それはまさにあなたがやりたいことではありませんが、かなり近いです。