6

there is a good construct, allows to control win32com objects, like

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

... etc. Is there a way to get full list of available applications (*.Application) ?

UPD. Possible solution to get list via scanning registry key HKEY_CLASSES_ROOT for CLSID entries.

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)
"""

filtering list by code below (long and possibly unsafe operation), list can be got:

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
Fnord
  • 5,365
  • 4
  • 31
  • 48
Vova
  • 563
  • 8
  • 20

1 Answers1

11

You might find it helpful to use a dedicated COM browser. For instance, you can use the COM browser bundled with win32com to investigate available type libraries and their interfaces:

from win32com.client import combrowse
combrowse.main()

enter image description here

For information on how to go from the type library CLSID to the ProgID needed when dispatching, see this question.

fuglede
  • 17,388
  • 2
  • 54
  • 99
  • 1
    But not all 'classnames' can be opened with dispatch, please explain why. Should it have subfolder "CLSID" to be dispatched? – Vova Aug 12 '18 at 16:59
  • Hm, yeah, I was going to point you towards `HKEY_CLASSES_ROOT\Wow6432Node`, but that actually also contains unregistered keys. The COM browsers such as the one mentioned and `oleview` are probably better bets. Let me edit the answer accordingly. – fuglede Aug 12 '18 at 17:36
  • 1
    Note: calling `combrowse.main(modal=True)` did work for me (without the `modal=True` it'd not really be interactive). – Fabio Zadrozny Aug 19 '22 at 11:56