在pywin32中有没有解码数字COM错误码的方法

2024-05-29 11:47:54 发布

您现在位置:Python中文网/ 问答频道 /正文

下面是最近运行的一个不可靠的Python应用程序的堆栈跟踪的一部分,该应用程序控制另一个用Excel编写的应用程序:

pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2146788248), None)

显然出了问题。。。但是什么?[1] 这些COM错误代码似乎过于神秘。

如何解码此错误消息?是否有一个表允许我将这个数字错误代码转换成更有意义的代码?

[1]实际上我知道在这种情况下出了什么问题,它试图访问一个没有Name属性的Range对象上的Name prperty。。。不是所有的虫子都这么容易找到!


Tags: namecomnone应用程序堆栈错误exceptionerror
3条回答

这样做:

try:
    [whatever code]
except pythoncom.com_error as error:
    print(win32api.FormatMessage(error.excepinfo[5]))

有关在此处消化pythoncom.com_error对象的详细信息:http://docs.activestate.com/activepython/3.2/pywin32/com_error.html

是,请尝试win32api模块:

import win32api
e_msg = win32api.FormatMessage(-2147352567)

您可以获取从异常返回的任何代码并将它们传递给FormatMessage。你的例子有两个错误代码。

你没有做错什么。堆栈跟踪中的第一项(数字)是COM对象返回的错误代码。第二项是与错误代码相关联的描述,在本例中为“异常发生”。pywintypes.com_error已经为您调用了等效的win32api.FormatMessage(errCode)。我们马上看第二个号码。

顺便说一下,您可以使用Visual Studio中的“错误查找”实用程序(C:\ Program Files\Microsoft Visual Studio 9.0\Common7\Tools\ErrLook.exe)作为快速启动板来检查COM错误代码。该实用程序还为您调用FormatMessage并显示结果。并不是所有的错误代码都可以使用这个机制,但是很多都可以。那通常是我的第一站。

COM中的错误处理和报告有点混乱。我会给你一些背景资料。

所有COM方法调用都将返回一个名为HRESULT的数字代码,该代码可以指示成功或失败。COM中所有形式的错误报告都建立在这个基础之上。

这些代码通常用十六进制表示,但有时您会看到它们是32位的大数字,就像在堆栈跟踪中一样。对于常见的结果和问题有各种预定义的返回代码,或者对象可以在特殊情况下返回自定义的数字代码。例如,值0(称为S_OK)普遍表示“无错误”,0x80000002是E_OUTOFMEMORY。有时HRESULT代码由对象返回,有时由COM基础结构返回。

COM对象还可以通过实现名为IErrorInfo的接口来选择提供更丰富的错误信息。当一个对象实现IErrorInfo时,它可以提供关于发生了什么的各种详细信息,例如详细的自定义错误消息,甚至描述问题的帮助文件的名称。在VB6和VBA中。Err对象允许您访问所有这些信息(Err.Description,等等)。

更为复杂的是,后期绑定的COM对象(使用一种称为COM自动化或IDispatch的机制)添加了一些需要剥离的层来获取信息。Excel通常通过后期绑定进行操作。

现在让我们再看看你的情况。作为第一个数字,您得到的是一个相当通用的错误代码:DISP_E_EXCEPTION。注意:您通常可以通过google找到HRESULT的正式名称,尽管有时您必须使用hex版本才能找到任何有用的名称。

以DISP开头的错误是IDISPATCH错误代码。这个错误松散地意味着“对象抛出了一个COM异常”,更多的信息打包在其他地方(尽管我不太清楚在哪里;我必须查找它)。

根据我对pywintypes.com_error的理解,消息中的最后一个数字是对象在异常期间返回的实际错误代码。这是从VBA的Err.Number中得到的实际数字代码。

不幸的是,第二个代码-2146788248(0x800A9C68)在为自定义应用程序定义的错误消息保留的范围内(在VBA中:VbObjectError + someCustomErrorNumber),因此没有集中的含义。同样的数字对于不同的程序来说意味着完全不同的事情。

在这种情况下,我们已经到了死胡同:

The error code is "custom", and the application needs to document what it is, except that Excel doesn't. Also, Excel (or the actual source of the error) doesn't seem to be providing any more information via IErrorInfo.

Excel(至少对我来说)是臭名昭著的,因为来自自动化的神秘错误代码和导致它们的模糊情况。尤其是对于可以考虑“设计时错误”的错误(“您应该比调用对象中不存在的方法更清楚”)。与“无法读取名称属性”不同,您得到的是“运行时错误“1004”:应用程序定义的或对象定义的错误”(这是我刚刚通过尝试从Excel中的VBA访问范围上的名称属性而得到的)。那不是很有帮助。

该问题不会在Python或它与Excel的接口上路由。Excel本身无法解释发生了什么,甚至VBA也无法解释。

但是,上述一般程序仍然有效。如果以后从Excel中得到一个错误,您可能会得到一个更好的错误消息,您可以用同样的方法跟踪它。

祝你好运!

相关问题 更多 >

    热门问题