我有两个使用Main方法的程序集。
第一个组装(简化示例):
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
}
}
第二个:
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");
}
}
结果因我执行的程序而异。
如果我运行第二 Main
,我会得到:
A
C
B
并创建文件。我认为它是第二个应用程序有效的证据。
当我运行第一个 Main
时,我只得到:
A
并且文件没有出现。该应用程序不会崩溃,但它会挂起。
我已经在.NET 4和Mono 2.10.9以及3.0.3(~git head)上验证了它。
为什么?我怎么能覆盖这个问题?
我越来越困惑。
我对PathToSecondAssembly
有疑问。当二进制文件在保存文件夹中时,一切似乎都很好(在.NET 4.0上测试过,但我也认为是单声道)。
当我使用相对路径或到不同目录的路径时,结果如下:
FileNotFoundException
,但是显示的是。消息:
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),但不知怎的,异常出现了。
我真的不知道为什么。某种权限问题?如何克服这种情况?
答案 0 :(得分:0)
我有一次类似的问题(我没有做同样的事情,但是从第二个域创建第三个域的失败在我脑海中浮现了记忆,然后FileNotFoundException确认了“我的恐惧”)。 / p>
这不是什么好事。证据无法解决。 正如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个域名(依此类推),请继续将证据从一个“truster”传递给另一个“受托人”:
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();
}
}
希望这是问题。