问题
Is there a way to determine if a registered COM component is creatable as a stand-alone component simply by parsing the information available in the registry? In particular, by the information found in HKCR/ClsId?
My system has over 12,000 entries in this key, and I am already excluding any items that do not have an InProcServer32 or LocalServer32 key, but this only eliminates about half of the items. I believe there are still another couple thousand that are not creatable objects. I really don't want to have to attempt to do a CreateObject() on every one of them to distinguish the ones that can be created from the ones that cannot. Is there a more efficient way?
回答1:
Oleview
I used Oleview for this purpose (back in the day :))
Manual/programmatic
If I remember correctly (no Windows PC nearby):
- the class should link to a typelibrary
- the typelib will point to a binary (dll, ocx, exe)
- this binary contains the physical typelibrary, which you should parse
- the midl compiler can do that (generate stubs/C headers)
- oleview can do that (extract IDL)
- tlbimp can do that
- you can do it with Win32 API
- any creatable objects should be marked
coclass(notinterfaceorsource; there were also global modules which I suppose are creatable too: I'm just not sure whether they are defined as coclasses
Show me the code
It is possible to read the information within a type library with the ITypeLib and ITypeInfo interfaces. They can be created with the ICreateTypeLib and ICreateTypeInfo interfaces. However, the Microsoft IDL compiler (MIDL) is probably the only application to ever use ICreateType and ICreateTypeInfo.
A quick google turned up this useful page: Reading Type Libraries with C++.
It contains just the code to get started. Just to see whether it was worth anything, I fired up a cloud Windows instance, grabbed all the sources and compiled it.
In contrast with the options mentioned on the site, I simply compiled on windows with
cl.exe *.cpp /EHs ole32.lib oleaut32.lib
Just for fun, I compiled the stuff on Linux (64 bit) using MingW:
i586-mingw32msvc-g++ *.cpp -loleaut32 -lole32 -o Typelib.exe
To save you the work I have put a zip-file up for download containing:
win32_Unicode.cpp - sources by René Nyffenegger
win32_Unicode.h
TestTypelib.cpp
Typelib.cpp
Typelib.h
VariantHelper.cpp
VariantHelper.h
TestTypelib.exe - binary compiled on windows
A test run:
# linux: ./a.exe ~/.wine/drive_c/windows/system32/msxml6.dll
C:\Games\Stacko>TestTypelib.exe c:\Windows\System32\msxml6.dll
MSXML2: Microsoft XML, v6.0
Nof Type Infos: 149
IXMLDOMImplementation
----------------------------
Interface: Dispatch
functions: 8
variables: 0
Function : QueryInterface
returns : VT_VOID
flags :
invoke kind: function
params : 2
params opt : 0
Parameter : riid type = VT_PTR (VT_USERDEFINED (GUID)) in
Parameter : ppvObj type = VT_PTR (VT_PTR) out
Function : AddRef
returns : VT_UI4
flags :
invoke kind: function
params : 0
params opt : 0
(snip) and 15499 lines more
Concluding
I hope this gives you a good starting point in scanning your system for installed, creatable, COM components
回答2:
Depends what you mean by "createable". If it has a LocalServer32 or InprocServer32 key it should be locally creatable. It may also be creatable remotely if it has an AppID and the AppID has either LocalService or RemoteServer keys.
However consulting the registry will only answer the question "does it look like it ought to be creatable".
You might still not be able to create it:
- The registration might be broken, or "fossil" registry entries from uninstalled components.
- The component might be an internal Windows component of some sort that you have no idea how to use since it is intentionally not documented.
- The component might be an internal component of an installed application which has additional requirements not documented.
- You might not have permission.
There may be other components you could create:
- There might be registration-free COM components, such as WSC scriptlets.
- there might be registration-free COM DLLs. There is no law saying you have to be registered to be a COM component. Registration is an optional service that most people opt into.
So I guess the answer is you should be able to get a mostly complete list using the registry, but what is the list for?
Without knowing what you want the list for, it is impossible to know if the list is good enough.
来源:https://stackoverflow.com/questions/6670548/discovering-registered-com-components