【问题标题】:How to use win32com to handle overflow when querying Desktop Search?查询桌面搜索时如何使用win32com处理溢出?
【发布时间】:2018-11-19 01:51:25
【问题描述】:

我正在使用 Python + ADO 查询 Windows Desktop Search JET (ESE) 数据库。它可以工作,但是在使用 MoveNext 前进到下一条记录时,在 ~7600 条记录之后出现异常。我知道它不在 EOF,因为我可以在 VBScript 中运行相同的查询并使用相同的查询获得更多记录。

异常回溯

Traceback (most recent call last):
  File "test_desktop_search.py", line 60, in <module>
    record_set.MoveNext()
  File "<COMObject ADODB.Recordset>", line 2, in MoveNext
pywintypes.com_error: (-2147352567, 'Exception occurred.', (0, None, None, None, 0, -2147215865), None)

Querying that error 显示是:

  • 常量: adErrDataOverflow
  • 值: 3721 -2146824567 0x800A0E89
  • 说明:数据值太大,字段数据类型无法表示。

这在 VBScript 中运行良好(但可能只是由于错误处理不当)。 PowerShell 出现以下错误(在比 Python 走得更远之后,与 VBScript 差不多):

Exception from HRESULT: 0x80041607
At C:\Users\doday\PycharmProjects\desktop_search_test\Get-DesktopSearchData.ps1:43 char:5
+     $recordSet.MoveNext();
+     ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : OperationStopped: (:) [], COMException
    + FullyQualifiedErrorId : System.Runtime.InteropServices.COMException

我在 Microsoft 文档中找不到此错误代码,但它可能是相关的。如您所见,Facility 字段为 4(特定于接口的 HRESULT 错误),代码为 1607。

MCVE

#!/usr/bin/env python
"""
Test querying Desktop Search from Python
"""

import csv
import pywintypes
from win32com.client import Dispatch

# connection
conn = Dispatch("ADODB.Connection")
connstr = "Provider=Search.CollatorDSO;Extended Properties='Application=Windows';"
conn.Open(connstr)

# record set
record_set = Dispatch("ADODB.Recordset")
q = "SELECT System.ItemName, System.ItemTypeText, System.Size, System.IsDeleted, System.DateAccessed, System.Kind, System.ItemDate, System.Search.Store, System.ItemParticipants, System.ItemAuthors, System.IsRead, System.Message.AttachmentNames FROM SystemIndex"
# record_set.ActiveConnection = conn
record_set.Open(q, conn)

# header
# I'm only selecting a few fields for this test, see
# https://msdn.microsoft.com/en-us/library/windows/desktop/bb419046(v=vs.85).aspx
header = [
    "System.ItemName",
    "System.ItemTypeText",
    "System.Size",
    "System.IsDeleted",
    "System.DateAccessed",
    "System.Kind",
    "System.ItemDate",
    "System.Search.Store",
    "System.ItemParticipants",
    "System.ItemAuthors",
    "System.IsRead",
    "System.Message.AttachmentNames"
]

# output to file
with open("ds_output.tsv", "w", newline='') as out_f:
    w = csv.DictWriter(out_f, fieldnames=header, delimiter='\t')
    w.writeheader()
    record_set.MoveFirst()
    while not record_set.EOF:
        record = dict.fromkeys(header)

        # populate fields
        for h in header:
            record[h] = record_set.Fields.Item(h).Value

        # write record
        w.writerow(record)

        try:
            record_set.MoveNext()
        except pywintypes.com_error as e:
            # can't figure out how to resolve this or at least advance to next record despite this error
            print("Error: {}".format(e.args))

# clean up
record_set.Close()
record_set = None
conn.Close()
conn = None

到目前为止我已经尝试过什么

  • 我尝试从我的查询中删除"System.Message.AttachmentNames" 列/字段,但这实际上使它失败得更快/在更少的记录之后出现相同的错误(异常args 中的第一个数字是相同的)。
  • 我尝试只使用一个字段 ("System.ItemName"),这使得它比 Python 中的其他尝试多一倍,但最终在 UnicodeEncodeError 上失败(这似乎与上面显示的另一个错误无关,这会阻止它永远不会成为具有该错误的文件名)。
  • 我尝试使用 PowerShell,还收到了COMException(如上所示的错误输出)。

【问题讨论】:

  • P.S.我的实际代码使用标题列表构建查询,所以我知道不是这样。是的,我按原样运行了这个 MCVE,得到了相同的结果/异常。
  • 0x80041607 seems to be QUERY_E_TIMEDOUT。它还匹配十进制数 -2147215865。如有时间设置值或参数请尝试更改。
  • 您的 trackback 显示了一个 -2147352567,它是 DISP_E_EXCEPTION(通用 COM 异常),包装了一个 -2147215865 错误,它是 0x80041607,它是 QUERY_E_TIMEDOUT(我使用这个工具 - 我做到了 - 来查找错误和其他常量:magnumdb.com/search?q=-2147215865)。所以他们都报告相同的超时错误。您可以增加 ADO 超时。 social.technet.microsoft.com/Forums/ie/en-US/…
  • @SimonMourier 谢谢!

标签: python com ado win32com desktop-search


【解决方案1】:

您的引用显示了 -2147352567 错误代码。这是 DISP_E_EXCEPTION,一个非常通用的 COM 异常。 它包装了一个-2147215865错误,也是0x80041607,也是QUERY_E_TIMEDOUT。

我使用这个免费的网站工具 - 我做到了 - 来查找错误和其他类似的常量:https://www.magnumdb.com/search?q=-2147215865

所以,事实上,它们都报告了相同的超时错误。

您可以按此处所述增加 ADO 超时:Having Problems With SystemIndex (I Love It But Can't Make It Work How I Want)

或者你可以完全删除它,使用如下代码:

conn.CommandTimeout = 0

【讨论】:

  • 再次感谢! +1 并标记为已接受。我希望我可以为 magnumdb 站点投票 10 次——这将使我的 C++/etc./COM 编程生活在解释 HRESULT 时变得更加轻松!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-25
  • 1970-01-01
相关资源
最近更新 更多