Win32com获取可用应用程序列表。

6

有一个很好的结构,可以控制Win32com对象,例如:

win32com.client.Dispatch('Word.Application')
win32com.client.Dispatch('Excel.Application')

有没有一种方法可以获取可用应用程序(*.Application)的完整列表?
更新。通过扫描注册表键HKEY_CLASSES_ROOT中的CLSID条目,可以获取列表的可能解决方案。
import winreg
from collections import OrderedDict
def myScan():
    
    result = OrderedDict(); i = 0
    while True:
        try:
            a1 = winreg.OpenKey(aReg, winreg.EnumKey(winreg.HKEY_CLASSES_ROOT, i))
            if i%1000==0:
                print(i,'processing')
            j = 0
            while True:
                try:
                    #print(j)
                    a2 = winreg.EnumKey(a1,j)
                    if a2=='CLSID':
                        kkkey = winreg.EnumKey(winreg.HKEY_CLASSES_ROOT,i)
                        vvvalue = winreg.EnumValue(winreg.OpenKey(a1,a2),0)
                        result[kkkey] = vvvalue
                        break
                    j+=1
                except OSError:
                    break
            i+=1
        except OSError:
            break
    return result

result = myScan() #candidates
print(len(res)) # 3363
keys_ = list(result.keys())
#retrieving part of result
for i in keys_[:10]:
    print(i,'=>',result[i])
"""
AccClientDocMgr.AccClientDocMgr => ('', '{FC48CC30-4F3E-4fa1-803B-AD0E196A83B1}', 1)
AccClientDocMgr.AccClientDocMgr.1 => ('', '{FC48CC30-4F3E-4fa1-803B-AD0E196A83B1}', 1)
AccDictionary.AccDictionary => ('', '{6572EE16-5FE5-4331-BB6D-76A49C56E423}', 1)
AccDictionary.AccDictionary.1 => ('', '{6572EE16-5FE5-4331-BB6D-76A49C56E423}', 1)
Access.ACCDAExtension => ('', '{73A4C9C1-D68D-11D0-98BF-00A0C90DC8D9}', 1)
Access.ACCDCFile => ('', '{73A4C9C1-D68D-11D0-98BF-00A0C90DC8D9}', 1)
Access.ACCDCFile.14 => ('', '{73A4C9C1-D68D-11D0-98BF-00A0C90DC8D9}', 1)
Access.ACCDEFile => ('', '{73A4C9C1-D68D-11D0-98BF-00A0C90DC8D9}', 1)
Access.ACCDEFile.14 => ('', '{73A4C9C1-D68D-11D0-98BF-00A0C90DC8D9}', 1)
Access.ACCDRFile.14 => ('', '{73A4C9C1-D68D-11D0-98BF-00A0C90DC8D9}', 1)
"""

通过下面的代码筛选列表(长时间且可能不安全的操作),可以获取列表:

import pywintypes
for i in range(len(keys_)):
    try:
        if i%100==0: print(i,'processing')
        app = win32com.client.Dispatch(keys_[i]) #possibly unsafe; for example, word.Quit() is necessary to do
        finalList.append(keys_[i])
    except pywintypes.com_error:
        pass

在你更新的代码中,aReg变量是什么? - Fnord
areg=winreg.HKEY_CLASSES_ROOT - cdummy
1个回答

11

使用专用的COM浏览器可能会有所帮助。例如,您可以使用与win32com捆绑在一起的COM浏览器来调查可用的类型库及其接口:

from win32com.client import combrowse
combrowse.main()

输入图片描述

关于如何从类型库CLSID转换为调度所需的ProgID,请参见此问题


1
但并非所有的“classnames”都可以使用dispatch打开,请解释为什么。它是否应该有子文件夹“CLSID”才能被分派? - Vova
嗯,是的,我本来想指向 HKEY_CLASSES_ROOT\Wow6432Node,但那里实际上也包含了未注册的键。像提到的那个 COM 浏览器和 oleview 这样的工具可能更好一些。让我相应地编辑答案。 - fuglede
1
注意:对于我而言,调用combrowse.main(modal=True)是有效的(如果没有modal=True,它就不会真正交互)。 - Fabio Zadrozny

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接