Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/26.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何引用所有正在运行的Excel应用程序实例的COM对象,包括隐藏的和没有工作簿的?_Excel_Winapi_Com_Pseudocode - Fatal编程技术网

如何引用所有正在运行的Excel应用程序实例的COM对象,包括隐藏的和没有工作簿的?

如何引用所有正在运行的Excel应用程序实例的COM对象,包括隐藏的和没有工作簿的?,excel,winapi,com,pseudocode,Excel,Winapi,Com,Pseudocode,如何获取每个正在运行的Excel应用程序实例的引用的完整列表(无论它们的工作簿数量和可见性状态如何) 我知道我可以使用Windows API查找每个Excel工作簿窗口(窗口类名为EXCEL7),获取它们的句柄以用于函数,然后分派并获取应用程序对象 尽管这只适用于至少有一个工作簿可见的Excel应用程序实例。如何获取隐藏和/或没有工作簿的Excel应用程序实例 Excel应用程序实例窗口(具有窗口类名XLMAIN)无法检索任何可访问对象 我正在寻找一个解释,有没有伪代码,或者任何编程语言的代码

如何获取每个正在运行的Excel应用程序实例的引用的完整列表(无论它们的工作簿数量和可见性状态如何)


我知道我可以使用Windows API查找每个Excel工作簿窗口(窗口类名为
EXCEL7
),获取它们的句柄以用于函数,然后分派并获取应用程序对象

尽管这只适用于至少有一个工作簿可见的Excel应用程序实例。如何获取隐藏和/或没有工作簿的Excel应用程序实例

Excel应用程序实例窗口(具有窗口类名
XLMAIN
)无法检索任何可访问对象


我正在寻找一个解释,有没有伪代码,或者任何编程语言的代码,只要我能够理解并实现它(在Python中)。

我想在Python中实现它,尽管我问这个问题时不要求答案是关于Python的,因为这是一个一般性的解释(不必特定于编程语言)可能就足够了

查看了模块在Python中实现的
GetObject
VB函数的源代码后,我注意到它调用了
monike
函数:

def Moniker(Pathname, clsctx = pythoncom.CLSCTX_ALL):
  """
    Python friendly version of GetObject's moniker functionality.
  """
  moniker, i, bindCtx = pythoncom.MkParseDisplayName(Pathname)
  dispatch = moniker.BindToObject(bindCtx, None, pythoncom.IID_IDispatch)
  return __WrapDispatch(dispatch, Pathname, clsctx=clsctx)
这个函数引导我找到了我不知道的函数

在搜索了有关它的多段代码并尝试将它们放在一起以执行我想要的操作而不引发错误,并确保它只获取Excel应用程序实例(我在代码中添加了Microsoft Word以演示如何使用其他COM对象)而不重复之后,我将下面的代码放在一起

from pythoncom import CreateBindCtx as create_bind_context, GetRunningObjectTable as get_running_object_table, IID_IDispatch as dispatch_interface_iid
from win32com.client import Dispatch as dispatch

running_object_table = get_running_object_table()
bind_context = create_bind_context()
excel_application_class_clsid = '{00024500-0000-0000-C000-000000000046}'
word_application_class_clsid = '{000209FF-0000-0000-C000-000000000046}'
excel_application_clsid = '{000208D5-0000-0000-C000-000000000046}'
word_application_clsid = '{00020970-0000-0000-C000-000000000046}'
excel_applications = []

for moniker in running_object_table:
  name = moniker.GetDisplayName(bind_context, None)
  if all(clsid not in name for clsid in [excel_application_class_clsid, word_application_class_clsid]):
    continue
  unknown_com_interface = running_object_table.GetObject(moniker)
  dispatch_interface = unknown_com_interface.QueryInterface(dispatch_interface_iid)
  dispatch_clsid = str(dispatch_interface.GetTypeInfo().GetTypeAttr().iid)
  if dispatch_clsid not in [excel_application_clsid, word_application_clsid]:
    continue
  com_object = dispatch(dispatch=dispatch_interface)
  excel_application = com_object.Application
  if id(excel_application) not in [id(excel_application) for excel_application in excel_applications]:
    excel_applications.append(excel_application)

input(excel_applications)
如果检查是我发现的过滤掉我不想要的东西的方法,尽管我不确定这是否是一个好方法

这个(包含win32com模块以及)给了我很大的帮助,和它一起,我学到了很多关于COM的知识

对于任何想用另一种编程语言进行此操作的人来说,查看上面代码中使用的内容应该很简单。下面列出了需要帮助的主要内容:、、和


不带Word的Excel实例的特定函数:

from pythoncom import (
  CreateBindCtx         as create_bind_context_com_interface,
  IID_IDispatch         as dispatch_com_interface_iid,
  GetRunningObjectTable as get_running_object_table_com_interface,
)
from win32com.client import (
  Dispatch as dispatch,
)

def get_excel_instances():
  '''
  Returns a list of the running Microsoft Excel application
  instances as component object model (COM) objects.
  '''
  running_object_table_com_interface = get_running_object_table_com_interface()
  bind_context_com_interface = create_bind_context_com_interface()
  excel_application_class_clsid = '{00024500-0000-0000-C000-000000000046}'
  excel_application_clsid = '{000208D5-0000-0000-C000-000000000046}'
  excel_instance_com_objects = []
  for moniker_com_interface in running_object_table_com_interface:
    display_name = moniker_com_interface.GetDisplayName(bind_context_com_interface, None)
    if excel_application_class_clsid not in display_name:
      continue
    unknown_com_interface = running_object_table_com_interface.GetObject(moniker_com_interface)
    dispatch_com_interface = unknown_com_interface.QueryInterface(dispatch_com_interface_iid)
    dispatch_clsid = str(object=dispatch_com_interface.GetTypeInfo().GetTypeAttr().iid)
    if dispatch_clsid != excel_application_clsid:
      continue
    excel_instance_com_object = dispatch(dispatch=dispatch_com_interface)
    excel_instance_com_objects.append(excel_instance_com_object)
  return excel_instance_com_objects

excel_instances = get_excel_instances()
input()

您可以使用,例如:
ExcelApplication=GetObject(,“Excel.Application”)
,然后遍历
ExcelApplication。工作簿
@DrakeWu MSFT
GetObject
仅返回活动实例。您可以列出所有进程,并仅筛选名为“Excel”的进程。也许这会有所帮助:@FoxfireAndBurnsAndBurns我正在尝试访问COM对象。我想我无法从进程中获取它们。