You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Win10+VS2017下C# AppDomain因CodeAccessPermission报错,如何修复?

问题分析与修复方案

首先,你的异常根源是新创建的AppDomain权限集限制了对c:\git目录的文件操作,具体原因和修复步骤如下:

问题根源

你给secureDomain配置的权限集中,对整个c:\设置了FileIOPermissionAccess.NoAccess:

perm.AddPermission( new FileIOPermission(FileIOPermissionAccess.NoAccess, @"c:\"));

这意味着该AppDomain下运行的所有代码都无法访问C盘的任何位置,包括你要写入的c:\git目录。而ThirdParty的构造函数是在secureDomain中执行的(通过CreateInstanceAndUnwrap),自然会触发权限检查失败。

修复步骤

1. 调整文件权限设置

修改权限集,给c:\git目录授予写入+路径发现权限(路径发现权限PathDiscovery是解析目录路径必需的):

var perm = new PermissionSet(PermissionState.None);
perm.AddPermission(new SecurityPermission(SecurityPermissionFlag.Execution));
// 替换原来的NoAccess设置,允许c:\git的写入和路径访问
perm.AddPermission(new FileIOPermission(
    FileIOPermissionAccess.Write | FileIOPermissionAccess.PathDiscovery, 
    @"c:\git"));

2. 优化AppDomain对象的运行方式(可选但推荐)

你的ThirdParty标记为[Serializable],这会导致对象被序列化回当前AppDomain。如果希望ThirdParty的逻辑完全在secureDomain中执行,建议让它继承MarshalByRefObject,这样CreateInstanceAndUnwrap会返回一个代理,所有操作都会转发到目标域:

// 替换原来的Serializable标记,改为继承MarshalByRefObject
public class ThirdParty : MarshalByRefObject
{
    public ThirdParty()
    {
        Console.WriteLine("3p loading");
        using (var file = System.IO.File.Create(@"c:\git\test.txt"))
        {
            // 建议using包裹File.Create,确保文件流被正确释放
        }
    }
}

3. 完整修改后的代码

class UseAppDomain {
    public static void Test() {
        var perm = new PermissionSet(PermissionState.None);
        perm.AddPermission( new SecurityPermission(SecurityPermissionFlag.Execution));
        // 授予c:\git目录的写入和路径发现权限
        perm.AddPermission(new FileIOPermission(
            FileIOPermissionAccess.Write | FileIOPermissionAccess.PathDiscovery, 
            @"c:\git"));
        
        var setup = new AppDomainSetup();
        setup.ApplicationBase = AppDomain.CurrentDomain.SetupInformation.ApplicationBase;
        
        AppDomain secureDomain = AppDomain.CreateDomain("secure", null, setup, perm);
        Type thirdPartyType = typeof(ThirdParty);
        // 创建代理对象,逻辑在secureDomain中执行
        secureDomain.CreateInstanceAndUnwrap(thirdPartyType.Assembly.FullName, thirdPartyType.FullName);
        
        AppDomain.Unload(secureDomain);
    }
}

public class ThirdParty : MarshalByRefObject {
    public ThirdParty() {
        Console.WriteLine("3p loading");
        // 使用using确保文件流被释放,避免文件被占用
        using (System.IO.File.Create(@"c:\git\test.txt"))
        {
            Console.WriteLine("文件创建成功");
        }
    }
}

额外注意事项

  • 确保你的VS2017以管理员权限运行,否则即使代码权限设置正确,系统层面的UAC可能会阻止文件创建。
  • File.Create会返回一个文件流,务必释放它(用using包裹是最佳实践),否则文件会被锁定无法后续操作。

内容的提问来源于stack exchange,提问作者Troskyvs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:25:39