C# appDomain 因 "CodeAccessPermission" 原因无法工作,为什么?
C# appDomain failed to work for "CodeAccessPermission" reason, why?
我正在使用 vs2017 在 win10 上尝试 C# appdomain,我有这个快速示例。我有一个名为 c:\git 的目录,我可以用 C# app 在这个目录下创建文件,但是当我尝试 app domain 时,它抛出异常,我的代码如下:
class UseAppDomain
{
public static void Test()
{
var perm = new PermissionSet(PermissionState.None);
perm.AddPermission(
new SecurityPermission(SecurityPermissionFlag.Execution));
perm.AddPermission(
new FileIOPermission(FileIOPermissionAccess.NoAccess, @"c:\"));
var setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
AppDomain secureDomain = AppDomain.CreateDomain("secure", null, setup, perm);
ThirdParty third = new ThirdParty();
Type thirdParty = typeof(ThirdParty);
secureDomain.
CreateInstanceAndUnwrap(thirdParty.Assembly.FullName,
thirdParty.FullName); //exception!!!!!!!!!!
AppDomain.Unload(secureDomain);
}
}
[Serializable]
class ThirdParty
{
public ThirdParty()
{
Console.WriteLine("3p loadling");
System.IO.File.Create(@"c:\git\test.txt");//Try to create file failed!
}
}
异常消息是:
Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, StackCrawlMark& stackMark)
at System.Security.CodeAccessPermission.Demand()
... ...
我不太明白我的程序有什么问题,如何解决这个问题?
谢谢。
如果您想从部分受信任的域创建文件,您需要改用 FileIOPermissionAccess.Write
。或者 FileIOPermissionAccess.AllAccess
如果您还想允许读取和目录内容发现。
旁注:
您将 CreateInstanceAndUnwrap
用于简单的可序列化 class,它不是从 MarshalByRefObject
派生的。它的效果是 class 将在创建的域中序列化,副本将在主域中反序列化,但是当您省略 return 值时,它无论如何都会被删除。
所以要么不要打开创建的对象,要么从 MarshalByRefObject
class 派生它,这样它的 public 成员就可以通过远程处理从主域访问。
我正在使用 vs2017 在 win10 上尝试 C# appdomain,我有这个快速示例。我有一个名为 c:\git 的目录,我可以用 C# app 在这个目录下创建文件,但是当我尝试 app domain 时,它抛出异常,我的代码如下:
class UseAppDomain
{
public static void Test()
{
var perm = new PermissionSet(PermissionState.None);
perm.AddPermission(
new SecurityPermission(SecurityPermissionFlag.Execution));
perm.AddPermission(
new FileIOPermission(FileIOPermissionAccess.NoAccess, @"c:\"));
var setup = new AppDomainSetup();
setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
AppDomain secureDomain = AppDomain.CreateDomain("secure", null, setup, perm);
ThirdParty third = new ThirdParty();
Type thirdParty = typeof(ThirdParty);
secureDomain.
CreateInstanceAndUnwrap(thirdParty.Assembly.FullName,
thirdParty.FullName); //exception!!!!!!!!!!
AppDomain.Unload(secureDomain);
}
}
[Serializable]
class ThirdParty
{
public ThirdParty()
{
Console.WriteLine("3p loadling");
System.IO.File.Create(@"c:\git\test.txt");//Try to create file failed!
}
}
异常消息是:
Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Security.SecurityException: Request for the permission of type 'System.Security.Permissions.FileIOPermission, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
at System.Security.CodeAccessSecurityEngine.Check(Object demand, StackCrawlMark& stackMark, Boolean isPermSet)
at System.Security.CodeAccessSecurityEngine.Check(CodeAccessPermission cap, StackCrawlMark& stackMark)
at System.Security.CodeAccessPermission.Demand()
... ...
我不太明白我的程序有什么问题,如何解决这个问题?
谢谢。
如果您想从部分受信任的域创建文件,您需要改用 FileIOPermissionAccess.Write
。或者 FileIOPermissionAccess.AllAccess
如果您还想允许读取和目录内容发现。
旁注:
您将 CreateInstanceAndUnwrap
用于简单的可序列化 class,它不是从 MarshalByRefObject
派生的。它的效果是 class 将在创建的域中序列化,副本将在主域中反序列化,但是当您省略 return 值时,它无论如何都会被删除。
所以要么不要打开创建的对象,要么从 MarshalByRefObject
class 派生它,这样它的 public 成员就可以通过远程处理从主域访问。