Can't create "Microsoft.Windows.ActCtx" object Topic is solved

Report problems with documented functionality
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Can't create "Microsoft.Windows.ActCtx" object

06 Sep 2019, 03:19

Error: 0x800401F3 - Invalid class string

Line#
---> 001: ComObjCreate("Microsoft.Windows.ActCtx")

VBS and JS doesn't have the problem.

Code: Select all

sc := ComObjCreate("ScriptControl")
sc.Language := "JScript"
sc.ExecuteStatement("ax = new ActiveXObject('Microsoft.Windows.ActCtx');")

sc := ComObjCreate("ScriptControl")
sc.Language := "VBScript"
sc.ExecuteStatement("Set actctx = CreateObject(""Microsoft.Windows.ActCtx"")")
return
Tested on 2 computers (Windows 10 and Windows 7)
lexikos
Posts: 9583
Joined: 30 Sep 2013, 04:07
Contact:

Re: Can't create "Microsoft.Windows.ActCtx" object

07 Sep 2019, 21:31

On my system, the string "Microsoft.Windows.ActCtx" cannot be found anywhere in the registry.

The class string is resolved by passing it to CLSIDFromString. AutoHotkey is not responsible for any part of this process; it just passes the string to CLSIDFromString and receives a CLSID or an error, and passes the CLSID to CoCreateInstance. You can replicate the error with Guid_FromStr:

Code: Select all

Guid_FromStr("Scripting.Dictionary", clsid)
MsgBox % Guid_ToStr(clsid)  ; Shows the CLSID.

Guid_FromStr("Microsoft.Windows.ActCtx", clsid)  ; Throws an exception.
MsgBox % Guid_ToStr(clsid)
Using Process Monitor while calling CreateObject showed different results for this and some other class that doesn't exist, so CreateObject is evidently identifying ActCtx before doing anything Process Monitor can detect, which means it does so without reading the registry. In other words...

CreateObject must be instantiating ActCtx through the use of registration-free activation, which I assume is what you want the ActCtx object for in the first place. :facepalm:

Process Monitor did show failed attempts to open a CLSID\{056EC0EB-79F7-4EBD-9B99-042EAE267CA0} reg subkey from different places. I could not find this CLSID in the SDK or by searching the Internet or my system (.dll and .manifest) files, but if I pass it to ComObjCreate, I get an ActCtx object.

Code: Select all

; Shows ActCtx.
MsgBox % ComObjType(ComObjCreate("{056EC0EB-79F7-4EBD-9B99-042EAE267CA0}"), "Class")


After further searching I eventually found CLSIDFromProgID (again). The documentation for this and CLSIDFromString is quite sparse. You may compare:
CLSIDFromString: Converts a string generated by the StringFromCLSID function back into the original CLSID.
CLSIDFromProgID: Looks up a CLSID in the registry, given a ProgID.
It might appear that CLSIDFromString only needs to handle GUID strings, since StringFromCLSID only ever returns strings in that format (because "StringFromCLSID calls the StringFromGUID2 function"). However, there's a clue that it handles ProgIDs in the list of error codes:
REGDB_E_CLASSNOTREG: The CLSID corresponding to the class string was not found in the registry.
By contrast, CLSIDFromProgID only handles ProgIDs. If we used it exclusively, we would be unable to instantiate classes that are registered only by CLSID... just like VBScript.

It appears that CLSIDFromProgID can resolve "Microsoft.Windows.ActCtx":

Code: Select all

VarSetCapacity(clsid, 16, 0)
r := DllCall("ole32\CLSIDFromProgID", "wstr", "Microsoft.Windows.ActCtx"
    , "ptr", &clsid)
MsgBox % r < 0 ? Format("Error {:x}", r & 0xFFFFFFFF) : Guid_ToStr(&clsid)
The documentation clearly indicates that it looks up the ProgID in the registry, but that is evidently not the only way it resolves a ProgID.

I will change ComObjCreate to use CLSIDFromProgID for non-GUID strings.
tmplinshi
Posts: 1604
Joined: 01 Oct 2013, 14:57

Re: Can't create "Microsoft.Windows.ActCtx" object

08 Sep 2019, 19:20

Thanks lexikos!

Your last code shows {C2346C9C-839C-4CCE-865D-D20CA6F78A18} on my system.
CreateObject must be instantiating ActCtx through the use of registration-free activation, which I assume is what you want the ActCtx object for in the first place. :facepalm:
Yes, I wanted to avoid using the extra manifest file, then I found Microsoft.Windows.ActCtx object has an ManifestText method. However it turns out it just creates a temporary manifest file when using ManifestText method. :problem:

Return to “Bug Reports”

Who is online

Users browsing this forum: No registered users and 51 guests