【问题标题】:C# appDomain failed to work for "CodeAccessPermission" reason, why?C# appDomain 因“CodeAccessPermission”原因而无法工作,为什么?
【发布时间】:2019-10-24 02:57:49
【问题描述】:

我正在使用 vs2017 在 win10 上尝试 C# appdomain,我有这个快速示例。我有一个名为 c:\git 的目录,我可以用 C# app 在这个目录下创建文件,但是当我尝试 app 域时,它会抛出异常,我的代码如下:

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()
... ...

我不太明白我的程序有什么问题,如何解决这个问题?

谢谢。

【问题讨论】:

    标签: c# file exception permissions appdomain


    【解决方案1】:

    如果您想从部分受信任的域创建文件,您需要改用FileIOPermissionAccess.Write。或者FileIOPermissionAccess.AllAccess,如果您还想允许读取和目录内容发现。

    旁注:

    您将CreateInstanceAndUnwrap 用于一个简单的可序列化类,它不是从MarshalByRefObject 派生的。它的效果是类将在创建的域中序列化,而副本将在主域中反序列化,但是当您省略返回值时,无论如何它都会被删除。

    因此,要么不要解开创建的对象,要么从MarshalByRefObject 类派生它,以便可以通过远程处理从主域访问其公共成员。

    【讨论】:

    • 我将权限更改为“AllAccess”,这次抛出了一个奇怪的异常: Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been throwed by the target of an invocation。 ---> System.IO.IOException: 该进程无法访问文件 'c:\git\test.txt' 因为它正被另一个进程使用----------------我删除了目标文件,再次运行我的程序,创建了文件,但仍然抛出相同的异常。那么这里发生了什么?
    • 是的,这是因为您已经在主域中创建了一个新的ThirdParty 实例,并且它使文件保持锁定状态。只需删除行ThirdParty third = new ThirdParty();
    • 是的,你说得对,我已经删除了这个多余的行,现在它可以工作了!
    猜你喜欢
    • 2012-12-04
    • 1970-01-01
    • 2017-04-29
    • 1970-01-01
    • 2011-09-02
    • 2022-11-04
    • 2017-04-10
    • 2011-10-02
    相关资源
    最近更新 更多