デフォルト (完全信頼) の AppDomain で、サンドボックス AppDomain を作成し、その中のイベントをサブスクライブしたいと考えています。
class Domain : MarshalByRefObject
{
public event Action TestEvent;
}
Domain domain = AppDomainStarter.Start<Domain>(@"C:\Temp", "Domain", null, true);
domain.TestEvent += () => { }; // SecurityException
サブスクリプションが失敗し、「タイプ 'System.Security.Permissions.ReflectionPermission, mscorlib, Version=4.0.0.0...' のアクセス許可の要求が失敗しました」というメッセージが表示されます。
(AppDomainStarter の定義については、別の質問に対する私の回答を参照してください。)
ApplicationBase
C:\Tempは、ドメインを含むアセンブリを含むフォルダーではないことに注意してください。これは意図的なものです。私の目標は、新しい AppDomain 内に 2 番目のサードパーティの信頼されていないアセンブリを読み込むことです。この 2 番目のアセンブリは C:\Temp (または他の場所、場合によってはネットワーク共有) にあります。Domain
ただし、2 番目のアセンブリを読み込む前に、新しい AppDomain 内にクラスを読み込む必要があります。これは成功しますが、何らかの理由で AppDomain 境界を越えてイベントをサブスクライブできません (メソッドを呼び出すことはできますが、イベントをサブスクライブすることはできません)。
UPDATE : 明らかに、サンドボックス AppDomain でイベントをサブスクライブする場合、サブスクライバー メソッドとサブスクライバーを含むクラスの両方がパブリックである必要があります。例えば:
public static class Program
{
class Domain : MarshalByRefObject
{
public event Action TestEvent;
public Domain() { Console.WriteLine("Domain created OK"); }
}
static void Main()
{
string loc = @"C:\Temp";
Domain domain = AppDomainStarter.Start<Domain>(loc, "Domain", null, true);
// DIFFERENT EXCEPTION THIS TIME!
domain.TestEvent += new Action(domain_TestEvent);
}
public static void domain_TestEvent() { }
}
しかし、私はまだイベントにサブスクライブできません。新しいエラーは、「ファイルまたはアセンブリ 'TestApp、Version=1.0.0.0、Culture=neutral、PublicKeyToken=null' またはその依存関係の 1 つを読み込めませんでした。指定されたファイルが見つかりません」です。
新しい AppDomain の ApplicationBase として「間違った」フォルダ「C:\Temp」を指定したため、これはある意味では理にかなっていますが、「TestApp」アセンブリが両方の AppDomain に既に読み込まれているため、ある意味でこれはまったく意味がありません。 . CLR が既に読み込まれているアセンブリを見つけられない可能性はありますか?
さらに、アセンブリを含むフォルダーへのアクセス許可を追加しても違いはありません。
string folderOfT = Path.GetFullPath(Path.Combine(typeof(T).Assembly.Location, ".."));
permSet.AddPermission(new FileIOPermission(FileIOPermissionAccess.Read, folderOfT));
// Same exception still occurs
に別の値を使用して問題を「修正」できますAppDomainSetup.ApplicationBase
。
string loc = Path.GetFullPath(Assembly.GetExecutingAssembly().Location + @"\..");
これにより例外は排除されますが、AppDomain の目的は、独自のアセンブリを含むフォルダーとは別のフォルダーから信頼されていないアセンブリを読み込むことであるため、この "解決策" を使用できません。したがって、loc
自分のアセンブリを含むフォルダーではなく、信頼されていないアセンブリを含むフォルダーである必要があります。