ClickOnce应用订阅AppDomain.UnhandledException抛出MethodAccessException如何解决
异常触发原因
- 核心为ClickOnce部署的默认安全权限限制:本地直接运行时应用获得当前用户的完全信任权限,而ClickOnce默认采用Internet区域的部分信任安全策略,未授予操作AppDomain所需的
SecurityPermission权限(需要ControlAppDomain权限位才能订阅AppDomain.UnhandledException事件),因此触发权限校验失败抛出MethodAccessException。 - 若你引用的外部程序集
MyLib为强签名程序集,默认未添加AllowPartiallyTrustedCallers特性时,部分信任环境下的跨程序集成员访问也会触发该异常。
解决方案
方案1:配置ClickOnce完全信任部署(推荐,操作最简单)
直接在项目属性中修改ClickOnce安全配置:
- 打开WPF项目的「属性」面板,切换到「安全」选项卡
- 勾选「启用ClickOnce安全设置」
- 选择「这是完全信任的应用程序」后重新打包发布即可
该方案适合应用部署在可信内网环境、或可以向用户说明完全信任必要性的场景。
方案2:仅申请必要权限(适合必须使用部分信任部署的场景)
如果必须保留部分信任安全策略,可单独授予所需权限:
- 同样在「安全」选项卡选择「这是部分信任的应用程序」,区域选择「自定义」
- 在权限列表中找到
SecurityPermission,勾选「授予程序集以下权限」 - 启用
ControlAppDomain权限位后重新打包
方案3:适配跨程序集权限校验
若外部程序集MyLib为强签名,需要在MyLib项目的AssemblyInfo.cs中添加以下特性:
[assembly: AllowPartiallyTrustedCallers]
同时可以将App类中的异常处理方法标记为SecuritySafeCritical避免权限校验拦截:
[SecuritySafeCritical] public void OnUnhandledException(object sender, UnhandledExceptionEventArgs eventArgs) { // 待实现 }
方案4:改用WPF原生异常事件(权限要求更低)
WPF本身提供了应用级别的未处理异常事件DispatcherUnhandledException,权限要求远低于AppDomain.UnhandledException,适配性更好,修改代码如下即可:
public App() { this.DispatcherUnhandledException += OnDispatcherUnhandledException; } private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e) { // 异常处理逻辑 e.Handled = true; // 标记异常已处理,避免应用直接退出 }
内容的提问来源于stack exchange,提问作者Jens
相关产品推荐
相关产品推荐

