6

2つの.NET管理アセンブリがあります。1つ目はメインアプリケーションで、もう1つは独立したツールです。

今私がしなければならないのは、小さなツールをメインアプリケーションと統合することです。したがって、ユーザーがメインアプリケーションのボタンをクリックすると、「ユーザー定義オブジェクト」を別の小さなツールに渡す必要があります。このツールは、別の異なる独立したプロセスに実行されます。

ただし、プロセスに送信できる文字列引数は1つだけです。

これを行うための最良のアプローチは何ですか?別のプロセスに送信する必要があるのは、各ファイルの設定を含むファイルのリストです。ここでの設定は私の「ユーザー定義オブジェクト」です。

これには別のひねりがあります。

初めてプロセスが実行されていない場合は、パラメータを送信してプロセスを実行します。しかし、プロセスが実行されている場合、パラメータを送信して、最初から再起動せずに既存のプロセスにデータを追加できますか?

それに関する助け。これを行う方法。

ありがとう

4

4 に答える 4

5

最も単純なレベルでは、シリアル化されたオブジェクトまたはその他の構成オプションを含むファイル(おそらく一時領域内)に場所を渡すことができます。

さらに興味深いことに、IPCチャネル情報(ソケットに接続するためのポート番号など)を渡して、リモーティング、WCF、rawソケットなど、任意の種類のIPCを確立できます。

于 2012-04-09T09:31:39.967 に答える
4

.NET 4は、メモリマップトファイルをサポートします。これは、プロセス間で任意のデータを共有するためのクリーンで便利な非常にパフォーマンスの高いメカニズムです(もちろん、一時ファイルへの書き込みなど、はるかにローテクな方法でこれを行うこともできます)。

メインプロセスから非永続メモリマップトファイルを作成し、そのファイルにユーザーオブジェクトのシリアル化された形式を書き込んでから、子プロセス内からオブジェクトを逆シリアル化することができます。オブジェクトクラスを(明らかに)シリアル化可能にし、メモリマップトファイルの名前をメインプロセスから子に渡す必要があります。ただし、名前は文字列であるため、コマンドライン引数として渡すことができます。

MSDNには、これを正確に行う方法の例もあります。

于 2012-04-09T09:32:02.450 に答える
1

私は今日同じ問題を経験しました。少なくとも、私はこの方法で問題を解決しました:

Newtonsoft.Json.dllを使用して、オブジェクトをシリアル化および逆シリアル化し、WM_COPYDATAメッセージを介して文字列を渡します。

ホストアプリの場合:

子アプリを呼び出す:

private void RunChild()
{
    string appPath = Path.GetDirectoryName(Application.ExecutablePath);
    string childPath = Path.Combine(appPath, "ChildApp.exe");
    Process.Start(childPath, this.Handle.ToString());
}

メッセージの受信:

protected override void WndProc(ref Message m)
{
    base.WndProc(ref m);
    switch (m.Msg)
    {
        case WM_COPYDATA:
            COPYDATASTRUCT copyData = new COPYDATASTRUCT();
            Type type = copyData.GetType();
            copyData = (COPYDATASTRUCT)m.GetLParam(type);
            string data = copyData.lpData;
            RestorePerson(data);
            break;
    }
}

オブジェクトを逆シリアル化します。

private void RestorePerson(string data)
{
    var p = JsonConvert.DeserializeObject<Person>(data);
    txtName.Text = p.Name;
    txtAge.Text = p.Age.ToString();
}

子アプリの場合:

ホストハンドルを取得します。

public ChildForm(string[] args)
{
    InitializeComponent();
    if (args.Length != 0)
        this.hostHandle = (IntPtr)int.Parse(args[0]);
}

シリアル化された文字列を送信します。

private void btnSubmit_Click(object sender, EventArgs e)
{
    this.person.Name = txtName.Text;
    this.person.Age = int.Parse(txtAge.Text);

    if (this.hostHandle != IntPtr.Zero)
    {
        string data = JsonConvert.SerializeObject(this.person);
        COPYDATASTRUCT cds = new COPYDATASTRUCT();
        cds.dwData = (IntPtr)901;
        cds.cbData = data.Length + 1;
        cds.lpData = data;
        SendMessage(this.hostHandle, WM_COPYDATA, 0, ref cds);
    }
}

//class Person can used by HostApp by add refrence.
[Serializable]
public class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

それはうまくいきます!それを試してみてください?

于 2017-03-17T06:41:09.010 に答える
0

上記の質問に対する2つの良い解決策を見つけました。

1)指定されたすべての入力を列として使用してデータテーブルを作成し、それをxmlとして書き込みます。そして、そのファイルを入力としてプロセスを開始し、そのxmlファイルを呼び出されたプロセスに読み込みます。このソリューションでは、新しいプロセスを制御できず、デバッグすることもできません。これをしている間、私は多くの複雑さを見つけました。

2)この解決策を見つけたら、解決策への参照としてexeを追加し、アセンブリへの単純な呼び出しとして、入力としてファイルを使用してそれを呼び出すだけです。これで、完全に制御できます。例外処理もできます。

返信ありがとうございます。

于 2012-04-10T05:27:59.320 に答える