如何检查文件是否打开(例如 Excel 工作簿)或是否已被用户使用 pywin32 COM 库关闭?

How to check if a file is open (e.g., Excel Workbook) or if its been closed by the user using pywin32 COM library?

有很多 VBA 和 C# 代码的示例,这些代码使用 Win API 检查工作簿是否打开用于 COM 对象,但是有 none 用于 python 使用 pywin32。我尝试使用像 GetObjectGetItem 这样的函数,但它们并非没有挑战。请参阅下面的代码片段以及我尝试检查用户是否已关闭工作簿的方法。它打开一个工作簿,然后保持打开状态十秒钟。如果用户关闭,就会发生精神错乱。有谁知道编写此代码的正确方法?谢谢!

# Open an excel, check if its open, wait until user closes or close it after ten seconds
def wait_until_time_or_user_close(excel, gencache=False):
    excel = win32.gencache.EnsureDispatch('Excel.Application')
    excel.Visible = True
    excel.DisplayAlerts = False
    wb_open = True
    try:
        wb = excel.Workbooks.Add()  # create new workbook
        name = ''.join(wb.Name)     # create a new string copy
                                    #  - needed because if user closes
                                    #    wb, then wb doesn't exist and
                                    #    wb.Name throws an error. 
        
        seconds = 0
        xl = None
        while(wb_open and seconds < 10):
            xl = win32.GetObject(name)
            # excel.Workbooks.getItem(name);  # produces AttributeError: 
                    # '<win32com.gen_py.Microsoft Excel 16.0 Object Library.Workbooks instance at 0x1548081920544>' 
                    # object has no attribute 'getItem' (or GetItem)
                    # Source: 
            wb_open = xl is not None

            # give user some time to interact
            import time
            time.sleep(1)
            seconds += 1
            
    finally:
        if wb_open:
            print("wb closed")
            wb.Close(False) # True=save the workbook, False=don't save workbook
        excel.Application.Quit()
excel = None
wait_until_time_or_user_close(excel)

此外,对于如何找出 COM 对象可用的不同函数和属性,有没有人有任何建议? pywin32 文档说明如下:

How do I know which methods and properties are available?
Good question. This is hard! You need to use the documentation with the products, or possibly a COM browser. Note however that COM browsers typically rely on these objects registering themselves in certain ways, and many objects to not do this. You are just expected to know.

它说你只是希望知道...好吧,如果是这样的话我去哪里知道这些东西????

可以在此处查看文档: http://timgolden.me.uk/pywin32-docs/html/com/win32com/HTML/QuickStartClientCom.html

这是解决问题的一种方法。添加第二个 try/catch 语句。如果有更好的方法来做到这一点 - 请推荐它们。此外,第二个问题仍然是了解 Win32 API.

的最佳方法。
# Open an excel, check if its open, wait until user closes or close it after ten seconds
def wait_until_time_or_user_close(excel, gencache=False):
    excel = win32.gencache.EnsureDispatch('Excel.Application')
    excel.Visible = True
    excel.DisplayAlerts = False
    wb_open = True
    try:
        wb = excel.Workbooks.Add()  # create new workbook
        seconds = 0
        xl = None
        while(wb_open and seconds < 10):
            try:
                xl = win32.GetObject(wb.Name)        
            except:
                wb_open = xl is not None

            # give user some time to interact
            import time
            time.sleep(1)
            seconds += 1
            
    finally:
        if wb_open:
            print("wb closed")
            wb.Close(False) # True=save the workbook, False=don't save workbook
        excel.Application.Quit()
excel = None
wait_until_time_or_user_close(excel)