调用OleDbConnection.Open()抛出AccessViolationException,本地正常服务器报错
问题根因
该System.AccessViolationException异常属于非托管COM组件环境不匹配导致的内存访问错误,仅在服务器出现、本地运行正常的核心原因是两端的ACE OLEDB Provider/ADOX/ADODB运行环境不一致,和托管代码逻辑本身没有直接关联。
排查&解决步骤
1. 匹配服务器ACE驱动位数
- 确认你本地和服务器安装的**Microsoft Access Database Engine(ACE OLEDB 12.0驱动)**位数完全对齐:项目编译目标为x86就装32位驱动,编译目标为x64就装64位驱动;如果用AnyCPU编译,要和服务器上服务的运行位数保持一致
- 服务器上如果有残留的旧版Access组件、Office自带的同类型驱动,先全部卸载干净再重装对应位数的官方驱动,避免多版本冲突
2. 修复COM对象释放逻辑
现有代码中catalog对象和关联的ADODB连接没有手动释放,残留的非托管句柄会和后续新建的OleDbConnection产生冲突,按如下方式修改代码即可解决大部分此类问题:
internal static bool CreateMDB(MySchemaClass schema, string filePath) { OleDbConnection conn = null; ADOX.Catalog catalog = null; ADODB.Connection adodbConn = null; bool status = true; string connectionString = string.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0}", filePath); try { // 新建MDB文件 catalog = new ADOX.Catalog(); catalog.Create(connectionString); adodbConn = (ADODB.Connection)catalog.ActiveConnection; if(adodbConn.State == ADODB.ObjectStateEnum.adStateOpen) { adodbConn.Close(); } // 手动释放COM对象,清理残留句柄 Marshal.ReleaseComObject(adodbConn); Marshal.ReleaseComObject(catalog); adodbConn = null; catalog = null; conn = new OleDbConnection(connectionString); conn.Open(); // 写入文件逻辑 WriteDataToFile(schema, conn); } catch (Exception ex) { status = false; // 建议在此处添加异常日志,方便后续定位问题 } finally { if (conn != null && conn.State == System.Data.ConnectionState.Open) { conn.Close(); conn.Dispose(); } // 异常场景下也要确保释放COM对象 if(adodbConn != null) Marshal.ReleaseComObject(adodbConn); if(catalog != null) Marshal.ReleaseComObject(catalog); } return status; }
3. 校验服务运行权限
- 确认服务的运行身份(如Local System、Network Service或自定义账号)对MDB文件的输出目录拥有完全控制权限
- 如果是IIS托管的服务,检查对应应用程序池的「启用32位应用程序」设置是否和项目编译位数匹配,同时把高级设置中的「加载用户配置文件」选项设为True
4. 兼容配置兜底
如果以上步骤都无法解决,在项目的App.config配置文件中添加如下配置,开启损坏状态异常捕获兼容:
<configuration> <runtime> <legacyCorruptedStateExceptionsPolicy enabled="true"/> </runtime> </configuration>
同时将项目的.NET Framework目标版本调整为和服务器上安装的.NET Framework版本完全一致,避免框架层兼容问题。
内容的提问来源于stack exchange,提问作者TS-
相关产品推荐
相关产品推荐

