4

Main メソッドを持つ 2 つのアセンブリがあります。

  • 最初のものは他のものを実行します。
  • 2 番目のアセンブリは、新しい AppDomain にオブジェクトを作成します。
  • そのオブジェクトは、ファイルを作成するか、画面に何かを印刷しようとしています。

最初のアセンブリ (簡略化された例):

class MainClass
{
    public static void Main(string[] args)
    {
        var domain = AppDomain.CreateDomain("server");
        new Task(() => domain.ExecuteAssembly(PathToSecondAssembly)).Start();
        new ManualResetEvent(false).WaitOne(); //wait forever
    }
}

2番目のもの:

class MainClass
{
    public static void Main(string[] args)
    {
        var domain = AppDomain.CreateDomain("name");
        Console.WriteLine ("A");

        domain.CreateInstance(Assembly.GetExecutingAssembly().FullName,
            typeof(Run).FullName, false, 0, null, 
            new object[0], null, new object[0]);

        Console.WriteLine ("B");
        new ManualResetEvent(false).WaitOne();
    }
}

class Run
{
    public Run()
    {
            File.Create("something");
            Console.WriteLine ("C");
    }
}

結果は、実行するプログラムによって異なります。

2 番目 を実行すると、次Mainのようになります。

A
C
B

とファイルが作成されます。2番目のアプリケーションが機能するという証拠として扱います。

最初 の を実行すると、Main以下のみが得られます。

A

ファイルが表示されません。アプリケーションはクラッシュしませんが、ハングします。

.NET 4 と Mono 2.10.9 および 3.0.3 (~git head) の両方で確認しました。

何故ですか?どうすればこの問題を無効にできますか?

==編集==

(.NET でテスト済み)

私はますます混乱しています。

に問題がありPathToSecondAssemblyます。バイナリが保存フォルダーにある場合、すべてが完全に問題ないようです (.NET 4.0 でテストされていますが、モノラルも想定しています)。

相対パスまたは別のディレクトリへのパスを使用すると、結果は次のようになります。

  • Visual Studio 2010 のデバッグでが表示されますがFileNotFoundExceptionA が表示されます。

メッセージ:

Could not load file or assembly 'test2, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null' or one of its dependencies.

最初のアセンブリの行で例外が発生します。

new Task(() => domain.ExecuteAssembly(PathToSecondAssembly)).Start();
  • デバッグなしで実行すると、A のみが出力されますが、何も起こりません。

したがって、アセンブリが見つかります(Aが出力されます)が、どういうわけか例外が発生します。

理由はまったくわかりません。ある種の権限の問題ですか?この状況をどのように克服しますか?

4

1 に答える 1

0

私はかつて同様の問題を抱えていました (私は同じことをしていませんでしたが、2 番目のドメインから 3 番目のドメインを作成できなかったことが頭の中で記憶を呼び起こし、FileNotFoundException のような「私の恐れ」が確認されました)。

それは何も良いことではありません 証拠は修正できません。MSDN が述べているように: http://msdn.microsoft.com/en-us/library/system.security.policy.evidence.aspx

証拠 セキュリティ ポリシーの決定への入力を構成する一連の情報を定義します。このクラスは継承できません。

だからこれをしてください:

class MainClass
{
  public static void Main(string[] args)
  {  
    var currentEvidence = AppDomain.CurrentDomain.Evidence;
    var domain = AppDomain.CreateDomain("server", securityInfo: currentEvidence);
    new Task(() => domain.ExecuteAssembly(PathToSecondAssembly)).Start();
    new ManualResetEvent(false).WaitOne(); //wait forever
  }
}

そして、4 番目のドメイン (など) を開始する予定がある場合は、ある「トラスター」から別の「トラスティ」に証拠を渡し続けます。

class MainClass
{
  public static void Main(string[] args)
  {
    var evAgain = AppDomain.CurrentDomain.Evidence;
    var domain = AppDomain.CreateDomain("name", securityInfo: evAgain);
    Console.WriteLine ("A");

    domain.CreateInstance(Assembly.GetExecutingAssembly().FullName,
        typeof(Run).FullName, false, 0, null, 
        new object[0], null, new object[0]);

    Console.WriteLine ("B");
    new ManualResetEvent(false).WaitOne();
  }
}

それが問題だったことを願っています。

于 2013-02-23T23:51:47.123 に答える