mhammond / pywin32

Python for Windows (pywin32) Extensions
4.92k stars 786 forks source link

pythoncom.CoCreateInstance always fail #2095

Closed AndrewChan2022 closed 11 months ago

AndrewChan2022 commented 11 months ago

create SetupConfigurationClass success, but fail

step 1. install visual studio on the windows, so there are com class SetupConfigurationClass

document here Microsoft.VisualStudio.Setup.Configuration

step 2. create com object of SetupConfigurationClass fail

import pythoncom, pywintypes

pythoncom.CoInitialize()

clsid = pywintypes.IID("{177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D}")
iid = pywintypes.IID("{42843719-DB4C-46C2-8E7C-64F1816EFD5B}")
obj = pythoncom.CoCreateInstance(clsid, None, 1, iid)
print(obj)

step 3. however using raw ctypes method success

import ctypes
from ctypes import *

class GUID(Structure):
    _fields_ = [("Data1", c_ulong),
                ("Data2", c_ushort),
                ("Data3", c_ushort),
                ("Data4", c_ubyte * 8)]

### init
ole32 = WinDLL('Ole32.dll')
CoInitialize = ole32.CoInitialize
CoUninitialize = ole32.CoUninitialize
CoCreateInstance = ole32.CoCreateInstance

rc = CoInitialize(None)

### create instance
clsid = GUID(0x177F0C4A, 0x1CD3, 0x4DE7,
        (0xA3, 0x2C, 0x71, 0xDB, 0xBB, 0x9F, 0xA3, 0x6D ))
iid = GUID(0x42843719, 0xDB4C, 0x46C2,
        (0x8E, 0x7C, 0x64, 0xF1, 0x81, 0x6E, 0xFD, 0x5B))
clsctx = 1
obj = c_void_p(None)
rc = CoCreateInstance(byref(clsid), 0, clsctx, byref(iid), byref(obj))
print(rc)
print(obj)

Name: pywin32 Version: 306

Python 3.11.4

mhammond commented 11 months ago

This is almost certainly because the interface in question doesn't support IDispatch

AndrewChan2022 commented 11 months ago

No, this component is used by customer to query visual studio version info, so no need support IDispatch and ole features.

As my understand, pythoncom is by design to support only subset of com that support IDispatch interface, so I need use other approach to get this non-ole component?

AndrewChan2022 commented 11 months ago

I using ctypes to accomplish this task.

I think COM without IDispatch maybe apply to lightweight tasks like finding VisualStudio installation.

https://github.com/AndrewChan2022/PyVisualStudioSetupConfiguration

mhammond commented 11 months ago

In that case I think you could have just use IID_IUnknown - but it sounds like there's nothing to do here.

AndrewChan2022 commented 11 months ago

yes, pythoncom also success when I change the iid to IUnknown, but still cannot query other interface by IUnknown :)

thanks.

import pythoncom, pywintypes

pythoncom.CoInitialize()

clsid = pywintypes.IID("{177F0C4A-1CD3-4DE7-A32C-71DBBB9FA36D}")
iid = pywintypes.IID("{00000000-0000-0000-C000-000000000046}")
obj = pythoncom.CoCreateInstance(clsid, None, 1, iid)
print(obj)

output:

<PyIUnknown at 0x000001DD5FEA20A0 with obj at 0x000001DD5FEA2190>