jugador Posted Thursday at 09:32 AM Posted Thursday at 09:32 AM (edited) If we use a known CLSID, such as {00024500-0000-0000-C000-000000000046} (Excel.Application), it works correctly. However, to test something I like to use custom clsid with ObjGet, I encounter the error 0x80040154: Class not registered. Local $oClsid = custom clsid Local $oTest = ObjGet("", $oClsid) or Local $oTest = ObjGet('clsid:' & $oClsid) I attempted to resolve this using CoCreateInstance($oClsid, 0, 0x1, IDispatch, 0), but CoCreateInstance also failed. I know I can make it work using GetActiveObject. However, my question is: Is there a way to make a custom CLSID work with ObjGet using a WinAPI call? Edited Thursday at 10:07 AM by jugador
jugador Posted 16 hours ago Author Posted 16 hours ago I use RegisterActiveObject to register custom clsid RegisterActiveObject creates item moniker ==> !{12345678-1234-1234-1234-56789ABCDEF0} So i tried Local $oTest = ObjGet('clsid:' & $oClsid) Local $oTest = ObjGet("moniker:!" & $oClsid) Local $oTest = ObjGet("item:" & $oClsid) but all this failed with custom clsid. Does any one have GetObject monikers complete list.
Numeric1 Posted 11 hours ago Posted 11 hours ago (edited) On 5/15/2025 at 9:32 AM, jugador said: If we use a known CLSID, such as {00024500-0000-0000-C000-000000000046} (Excel.Application), it works correctly. However, to test something I like to use custom clsid with ObjGet, I encounter the error 0x80040154: Class not registered. Local $oClsid = custom clsid Local $oTest = ObjGet("", $oClsid) or Local $oTest = ObjGet('clsid:' & $oClsid) I attempted to resolve this using CoCreateInstance($oClsid, 0, 0x1, IDispatch, 0), but CoCreateInstance also failed. I know I can make it work using GetActiveObject. However, my question is: Is there a way to make a custom CLSID work with ObjGet using a WinAPI call? Instead of using ObjGet, which can be limited by registration requirements in the Windows registry or the Running Object Table (ROT) and may cause errors like 0x80040154, you can achieve a better result by using the AutoItObject.au3 UDF. This library allows you to create a custom COM object, register it with a specific CLSID using _AutoItObject_RegisterObject, and reliably retrieve it with _AutoItObject_ObjCreate in the same script. This approach uses internal WinAPI calls (such as CoRegisterClassObject) to register the object in the ROT, fulfilling your requirement for a WinAPI-based solution while being simpler and more robust than ObjGet. The following example, adapted from the provided code, demonstrates how to create a COM object, register it with a custom CLSID, and retrieve it with _AutoItObject_ObjCreate to call its methods. expandcollapse popup#include "AutoItObject.au3" #include <MsgBoxConstants.au3> Opt("MustDeclareVars", 1) ; COM error handling Global $oError = ObjEvent("AutoIt.Error", "_ErrFunc") Func _ErrFunc() ConsoleWrite("COM Error, ScriptLine(" & $oError.scriptline & ") : 0x" & Hex($oError.number, 8) & " - " & $oError.windescription & @CRLF) EndFunc ; Initialize AutoItObject _AutoItObject_StartUp() ; Create the custom object Global $oObject = _SomeObject() ; Register the object with a custom CLSID Global Const $sMyCLSID = "{D07F2CEA-696F-47CD-99A9-D31E3641169A}" ; Custom CLSID Global $hObj = _AutoItObject_RegisterObject($oObject, $sMyCLSID) ; Retrieve the object with _AutoItObject_ObjCreate Global $oObjectNew = _AutoItObject_ObjCreate("cbi:" & $sMyCLSID) If Not IsObj($oObjectNew) Then MsgBox($MB_ICONERROR, "Error", "Failed to retrieve the object") Else $oObjectNew.MsgBox() ; Call the MsgBox method EndIf ; Unregister the object _AutoItObject_UnregisterObject($hObj) $oObject = 0 $oObjectNew = 0 ; Define the custom object Func _SomeObject() Local $oClassObject = _AutoItObject_Class() $oClassObject.Create() $oClassObject.AddMethod("MsgBox", "_Obj_MsgBox") $oClassObject.AddProperty("Title", $ELSCOPE_PUBLIC, "My Object") $oClassObject.AddProperty("Text", $ELSCOPE_PUBLIC, "Custom Text") $oClassObject.AddProperty("Flag", $ELSCOPE_PUBLIC, 64 + 262144) Return $oClassObject.Object EndFunc ; MsgBox method Func _Obj_MsgBox($oSelf, $sTitle = "") If $sTitle Then Return MsgBox($oSelf.Flag, $sTitle, $oSelf.Text) MsgBox($oSelf.Flag, $oSelf.Title, $oSelf.Text) EndFunc Initialization: _AutoItObject_StartUp() initializes the AutoItObject.au3 UDF. Object Creation: The _SomeObject function creates a COM object with a Title, Text, and Flag property, and a MsgBox method that displays a message. Registration: _AutoItObject_RegisterObject registers the object with the custom CLSID {D07F2CEA-696F-47CD-99A9-D31E3641169A} in the Running Object Table (ROT) using internal WinAPI calls (e.g., CoRegisterClassObject). Retrieval with _AutoItObject_ObjCreate: The object is retrieved in the same script using _AutoItObject_ObjCreate("cbi:" & $sMyCLSID), where the cbi: prefix indicates a local COM server. The MsgBox method is then called, displaying a dialog with the title "My Object" and text "Custom Text". Error Handling: A COM error handler (_ErrFunc) captures potential errors for debugging. Cleanup: The object is unregistered with _AutoItObject_UnregisterObject, and references are released. Why This Is Better Than ObjGet Reliability: _AutoItObject_ObjCreate is designed to work seamlessly with objects created and registered by AutoItObject.au3, avoiding errors like 0x80040154 ("Class not registered") that occur with ObjGet if the object is not properly registered. Simplicity: The UDF handles the necessary WinAPI calls (e.g., CoRegisterClassObject) internally, meeting your requirement for a WinAPI-based solution without needing manual WinAPI coding. Flexibility: You can define custom objects with specific methods and properties, as shown in the example, and manipulate them easily within the same script. Avoids ObjGet Limitations: ObjGet requires the object to be registered in the Windows registry or active in the ROT, which can be problematic for custom CLSIDs. _AutoItObject_ObjCreate is optimized for objects created by the UDF, making access more straightforward and less error-prone. Why This Addresses Your Question Custom CLSID: The example uses a custom CLSID ({D07F2CEA-696F-47CD-99A9-D31E3641169A}) to register and retrieve the object, meeting your need to work with a specific CLSID. WinAPI Call: _AutoItObject_RegisterObject uses internal WinAPI calls to register the object in the ROT, fulfilling your requirement for a WinAPI-based solution. Avoiding 0x80040154: By using _AutoItObject_ObjCreate instead of ObjGet, you bypass registration issues that cause the "Class not registered" error, as the UDF handles temporary registration in the ROT. Prerequisites Download AutoItObject.au3 from the AutoIt forum or official site and place it in the same folder as your script or in AutoIt’s include directory. Ensure your AutoIt version is up to date to guarantee compatibility with AutoItObject.au3. Tips Verify that the CLSID used in _AutoItObject_ObjCreate matches exactly the one defined in $sMyCLSID. Use the COM error handler (as shown) to diagnose potential issues. To add more methods or properties to the object, modify the _SomeObject function using _AutoItObject_Class().AddMethod or .AddProperty. Limitations Temporary Registration: Registration via _AutoItObject_RegisterObject is valid only during the script’s execution. For permanent registration in the Windows registry, you would need to create a COM DLL and register it with regsvr32, which is more complex. UDF Dependency: This example relies on AutoItObject.au3. If you prefer to avoid the UDF, you would need to implement manual WinAPI calls (e.g., RegisterActiveObject via dllcall), which is more complex and requires a valid COM object. Conclusion The AutoItObject.au3 UDF provides a more robust and simpler solution than ObjGet for working with custom CLSIDs. By using _AutoItObject_RegisterObject to register a COM object and _AutoItObject_ObjCreate to retrieve it, as shown in the example, you can avoid errors like 0x80040154 and meet your need for a WinAPI-based solution. This simplified example demonstrates how to create, register, and retrieve a COM object in the same script. Edited 11 hours ago by Numeric1
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now