4

C# コンソール プログラムを 2 つ実行しています。1つから、2番目のexeに何かをするように指示する必要がありますか? これどうやってするの?私は見た

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

しかし、ここから、exe のメソッドではなく、CommonAssembly(参照された dll) のメソッドを呼び出すことができます。

4

5 に答える 5

5

単純なシナリオでは、単純な古い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クラスを見てください。

  • どのプログラムがイベントを作成するかを検討します。イベントが存在しない場合は、作成するよりも両方のプログラムからイベントを開こうとすることができます。
  • プログラムの1つがサービスである(および/または他のセッション/ユーザーで実行されている)場合は、イベント名の前に「Global\」を付けます。そうしないと、Vista以降では機能しません。
  • イベントを作成するときに、他のセッションの他のプロセスから開くことができるように、セキュリティ属性を設定する必要がある場合があります。

WCF、Remoting、DCOM、CORBAなどの高度なIPCメカニズムは、トリガーや戻り値などのさまざまなアクションを備えたより複雑な通信プロトコルを使用している場合に適しています。単純なケース(カップル)の場合、Windowsイベントで十分です。

注意 プロセス間でデータを転送する必要がある場合は、メモリマップトファイルを検討してください。それらの「公式」.NETクラスは.NET4.0で利用可能になります。現在、http ://github.com/tomasr/filemap/tree/masterを使用できます。

于 2009-06-06T22:38:32.627 に答える
3

.NETでのプロセス間通信についてはWCFを調べてください。同じマシンまたはリモートマシンの通信に使用できるさまざまなプロトコルがあります。同じマシンの場合、名前付きパイプまたは.NETTCPバインディングを確認することをお勧めします。

WCFにはわずかな学習曲線がありますが、そこにはたくさんのチュートリアルがあり、それは間違いなく学ぶ価値のあるものです。

于 2009-06-06T22:09:50.703 に答える
2

私はこれにMSMQを頻繁に使用します。

http://www.csharphelp.com/archives3/archive581.html

于 2009-06-06T22:11:32.463 に答える
2

これでうまくいくはずです...

[コード]

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

[/コード]

于 2009-06-18T17:22:54.787 に答える
1

あなたはIPCを検討するかもしれません。 NamedPipeClientStreamNamedPipeServerStreamは非常に単純です。 以下は、IPC を使用して、アプリケーションのあるインスタンスから別のインスタンスにコマンド ライン引数を渡す例です。それはまさにあなたがやりたいことではありませんが、かなり近いです。

于 2009-06-06T23:10:40.707 に答える