OLEDB - C++ - ATL 的 OLEDB 提供程序示例使 Excel 崩溃(来自 msado15.dll 的未捕获异常)

Posted

技术标签:

【中文标题】OLEDB - C++ - ATL 的 OLEDB 提供程序示例使 Excel 崩溃(来自 msado15.dll 的未捕获异常)【英文标题】:OLEDB - C++ - ATL's OLEDB Provider sample crashes Excel (uncaught exception from msado15.dll) 【发布时间】:2018-12-15 11:45:06 【问题描述】:

我已经编译了来自运行VS2007 ATL OLEDB Provider wizard 的示例 OleDb 提供程序代码。我已经对该博客文章提供了更详细的信息。该代码使 Excel 崩溃。

Sub TestOleDbProvider()

    On Error GoTo ErrHand


    Dim cn As ADODB.Connection
    Set cn = New ADODB.Connection

    cn.Open "Provider=FindFiles;Server=foo;Database=bar" '* this works

    Dim cmd As ADODB.Command
    Set cmd = New ADODB.Command

    Set cmd.ActiveConnection = cn '* this works

    cmd.CommandText = "*.*"   '* this works

    Stop
    Dim rs As ADODB.Recordset
    Set rs = cmd.Execute '* crashes here

    Exit Sub
ErrHand:
    Debug.Print Err.Description & " (" & Err.Number & ")"
    'Stop

End Sub

上述代码在Set rs = cmd.Execute 行使Excel 崩溃。如果我从 VS2017 调试,我会得到未处理的异常

未捕获异常的 C++ 调用堆栈在这里

msado15.dll!CQuery::SetSQL(unsigned short *) Unknown Non-user code. Symbols loaded.
msado15.dll!CQuery::SetCommandText(long,unsigned long,unsigned char,unsigned char) Unknown Non-user code. Symbols loaded.
msado15.dll!CQuery::Execute(enum ExecuteTypeEnum,char,unsigned long,bool,unsigned long,unsigned long,long,struct tagVARIANT *,unsigned long,void *,long *,struct _ADORecordset * *) Unknown Non-user code. Symbols loaded.
msado15.dll!CCommand::_Execute(enum ExecuteTypeEnum,char,unsigned long,bool,unsigned long,unsigned long,long,long,struct tagVARIANT *,unsigned long,void *,long *,struct _ADORecordset * *) Unknown Non-user code. Symbols loaded.
msado15.dll!CCommand::ExecuteWithModeFlag(struct tagVARIANT *,struct tagVARIANT *,long,struct _ADORecordset * *,int) Unknown Non-user code. Symbols loaded.
msado15.dll!CCommand::Execute(struct tagVARIANT *,struct tagVARIANT *,long,struct _ADORecordset * *) Unknown Non-user code. Symbols loaded.
VBE7.DLL!1e813579() Unknown No symbols loaded.
[Frames below may be incorrect and/or missing, no symbols loaded for VBE7.DLL]  Annotated Frame
VBE7.DLL!1e7cff4b() Unknown No symbols loaded.
VBE7.DLL!1e829d13() Unknown No symbols loaded.
VBE7.DLL!1e82fea2() Unknown No symbols loaded.
VBE7.DLL!1e82bcb5() Unknown No symbols loaded.
[External Code]  Annotated Frame

调用堆栈显示在 msado15.dll 内明确引发的异常

我应该想象这个用例没有定期测试,但我会对任何建议感兴趣。

请问如何停止崩溃?

【问题讨论】:

由于它无法读取 0x00000000 而在 SetSQL(它需要一个 unicode 字符串)上崩溃,我们可以想象 SQL 文本为空。您是否尝试将cmd.CommandType = adCmdText 添加到您的示例代码中? @SimonMourier :这是一个很好的建议,应该包含在代码中。我刚刚添加,它仍然崩溃。还是谢谢。 它是否适用于这样的 C# 程序:pastebin.com/Y1yV7Qcw(它适用于我) 是的,它给出了输出!也许它绕过 msado15.dll 并改用 .NET 堆栈。我想知道如何从那里将数据导入 VBA。我需要反思一下。 .NET 直接通过 OLEDB,而 VB/VBA/VBScript 都使用与 COM 自动化兼容的 ADO(OLEDB 不兼容)。我可以用 VBScript 重现错误(我没有 excel 32b)。 【参考方案1】:

ADO,OLEDB 上的 COM 自动化包装器,查询 OLEDB 的 ICommandText 接口。而不是抱怨接口没有实现,它只是继续一个 NULL 命令文本并崩溃。

我以为这一切过去都可以工作,但由于某种原因(OLEDB 与 ADO 相结合是一项相当复杂的技术),支持命令的 ATL 模板实现了接口,但在查询时不响应。

因此,要解决此问题,只需将 ATL 条目添加到命令对象的服务接口即可:

BEGIN_COM_MAP(CFindFilesCommand)
    ...
    COM_INTERFACE_ENTRY(ICommandText) 
    ...
END_COM_MAP()

【讨论】:

以上是关于OLEDB - C++ - ATL 的 OLEDB 提供程序示例使 Excel 崩溃(来自 msado15.dll 的未捕获异常)的主要内容,如果未能解决你的问题,请参考以下文章

ADO数据库编程详解(C++)----初级入门篇

OleDb 异常 System.Data.OleDb.OleDbException (0x80004005): 超出系统资源

Microsoft.Jet.OLEDB.4.0 与 Microsoft.ACE.OLEDB.12.0,我应该使用哪个?

将连接字符串从 Microsoft.Jet.OLEDB.4.0 转换为 Microsoft.ACE.OLEDB.12.0 提供程序

OLEDB 与 ODBC [重复]

MSSQL"尚未注册OLEdB访问接口Microsoft.ACE.OLEDB.12.0"解决办法