Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
COM error Class not registered
#1
I used ChatGPT to modify the code in the following link.
https://github.com/qgindi/LibreAutomate/...Api_UIA.cs

I attempted to load the assembly using the following two methods:
/*/ com UIAutomationClient 1.0 #b183b9d9.dll; /*/
/*/ nuget -\Interop.UIAutomationClient; /*/

However, after execution, I encountered the same error. The error message is as follows:
System.Runtime.InteropServices.COMException (0x80040154): Retrieving the COM class factory for component with CLSID {30CBE57D-D9D0-452A-AB13-7AC5AC4825EE} failed due to the following error: 80040154 Class not registered (0x80040154 (REGDB_E_CLASSNOTREG)).
   at line 56 in Script7.cs, PowerShellCaretUtil.GetCaretRectInPowerShell(RECT& rect)
   at line 7 in Script7.cs
   >>


I don't quite understand the execution principle of the code, so there might need to be some changes.

Additionally, I am eager to know how to implement this functionality(GetCaretRectInPowerShell) in QM. I am using the following QM code, but I am still unable to achieve the desired functionality.

Thanks in advance for any suggestions and help
David

Function getISECaretPos
Trigger Ax     Help - how to add the trigger to the macro
 
Code:
Copy      Help
typelib UIAutomationClient {944DE083-8FB8-45CF-BCB7-C477ACB2F897} 1.0
UIAutomationClient.CUIAutomation automation
UIAutomationClient.IUIAutomationElement element

if automation.GetFocusedElement(&element)=0
,out 1

ChatGPT Code:
Code:
Copy      Help
// script ""
/*/ com UIAutomationClient 1.0 #b183b9d9.dll; /*/
/*/ nuget -\Interop.UIAutomationClient; /*/

using System;
using System.Runtime.InteropServices;

// Call the method to retrieve the text cursor position
if (PowerShellCaretUtil.GetCaretRectInPowerShell(out var rect))
{

    Console.WriteLine($"Caret Position: Left={rect.Left}, Top={rect.Top}, Right={rect.Right}, Bottom={rect.Bottom}");
}

else
{
    Console.WriteLine("Failed to get caret position.");
}


public static class PowerShellCaretUtil
{
    // Structure for rectangle
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }

    
    // UI Automation COM interface
    [ComImport, Guid("30cbe57d-d9d0-452a-ab13-7ac5ac4825ee")]
    internal class CUIAutomation { }
    
    // UI Automation element interface
    [ComImport, Guid("d22108aa-8ac5-49a5-837b-37bbb3d7591e")]
    [
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IUIAutomationElement
    {
        // Method to get the current bounding rectangle of an element
        [PreserveSig] int get_CurrentBoundingRectangle(out RECT retVal);
    }

    
    // UI Automation interface
    [ComImport, Guid("30cbe57d-d9d0-452a-ab13-7ac5ac4825ee")]
    [
InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
    internal interface IUIAutomation
    {
        // Method to get the focused element
        [PreserveSig] int GetFocusedElement(out IUIAutomationElement element);
    }

    
    // Method to get the text cursor position in PowerShell ISE
    public static bool GetCaretRectInPowerShell(out RECT rect)
    {

        rect = default;
        
        // Create UI Automation instance
        var automation = new CUIAutomation() as IUIAutomation;
        
        // Get the focused UI element
        if (0 == automation.GetFocusedElement(out var element))
        {

            // Get the bounding rectangle of the focused element
            if (0 == element.get_CurrentBoundingRectangle(out rect))
            {

                return true;
            }
        }

        
        return false;
    }
}
#2
ChatGPT just damaged the code.

If you want to use Interop.UIAutomationClient from nuget, here is an example.
Code:
Copy      Help
// script ""
/*/ nuget -\Interop.UIAutomationClient; /*/
using UIA = Interop.UIAutomationClient;

var uia = new UIA.CUIAutomation8Class() as UIA.IUIAutomation;
var e = uia.GetFocusedElement();
print.it(e.CurrentClassName);

QM example.
Code:
Copy      Help
typelib UIAutomationClient {944DE083-8FB8-45CF-BCB7-C477ACB2F897} 1.0
UIAutomationClient.CUIAutomation8 automation._create
UIAutomationClient.IUIAutomationElement element=automation.GetFocusedElement
out element.CurrentClassName
#3
The LA code uses raw function names and signatures.
UIAutomationClient changes them to make simpler.

Code:
Copy      Help
// script ""
/*/ nuget -\Interop.UIAutomationClient; /*/
using UIA = Interop.UIAutomationClient;

var uia = new UIA.CUIAutomation8Class() as UIA.IUIAutomation;
var e = uia.GetFocusedElement();
print.it(e.CurrentClassName);

var r = e.CurrentBoundingRectangle;
print.it(r.left, r.top, r.right, r.bottom);

//if you need RECT
RECT r2 = RECT.FromLTRB(r.left, r.top, r.right, r.bottom);
print.it(r2);
#4
Thanks for your help.
I just realized that the key to solving the problem lies in the following code.
It seems that many functions in the code are specific to LA, and converting them into generic C# code is too difficult for me.  Huh

I would like to convert it into generic C# code and then call it in the filtering function in QM.
 
Code:
Copy      Help
internal static bool GetCaretRectInPowerShell(out RECT r) {
        var t = ElementFocused();
        if (t != null && 0 == t.get_CurrentControlType(out var ct) && ct == UiaApi.TypeId.Edit) {
            if (0 == Uia.get_RawViewWalker(out var walker)) {
                UiaApi.IUIAutomationElement e = null;
                while (0 == (e == null ? walker.GetFirstChildElement(t, out e) : walker.GetNextSiblingElement(e, out e)) && e != null) {
                    //if (0 == e.get_CurrentControlType(out ct)) print.it(ct);
                    //if (0 == e.get_CurrentAutomationId(out var ai)) print.it(ai);
                    if (0 == e.get_CurrentAutomationId(out var ai) && ai.Find("Caret", true) >= 0 && 0 == e.get_CurrentControlType(out ct) && ct == UiaApi.TypeId.Custom) {
                        if (0 == e.get_CurrentBoundingRectangle(out r)) {
                            return true;
                        }
                    }
                }
                //There are 3 child elements. The first is caret.
                //This is slow. Tested MSAA, but it gets only child element "selection", and cannot get rect when selection empty.
            }
        }
        r = default;
        return false;
    }

I'm not sure if it's possible to implement similar code in QM like LA. If possible, that would be great because when using QM, many controls cannot find the text insertion point.
#5
They are not specific to LA. Please read my previous post. Easy to convert if you know standard rules how raw COM functions are converted to functions like in UIAutomationClient. The rules are not LA-specific.
#6
I tried to implement it using QM code, but still no luck.
The output result will not contain 'Caret'
However, success is very close

Function getISECaretPos
Trigger Ax     Help - how to add the trigger to the macro
Code:
Copy      Help
UIA.CUIAutomation u._create
UIA.IUIAutomationElement t=u.GetFocusedElement; out t.CurrentClassName
UIA.IUIAutomationElement e
UIA.IUIAutomationTreeWalker walker=u.RawViewWalker
e=walker.GetFirstChildElement(t)
e=walker.GetNextSiblingElement(e)

out e.CurrentControlType ;;Edit = 50004,Custom = 50025
out e.CurrentAutomationId ;;must Contains("Caret")

UIA.tagRECT r
r=e.CurrentBoundingRectangle
out r.left
out r.top
out r.right
out r.bottom
#7
In the above code: Only when selecting text can the position of the text as the target be obtained. See below pic

I do not understand how the code in LA achieves obtaining the position of the text cursor when text is not selected Huh
 if (0 == e.get_CurrentAutomationId(out var ai) && ai.Find("Caret", true) >= 0 && 0 == e.get_CurrentControlType(out ct) && ct == UiaApi.TypeId.Custom) {

https://i.ibb.co/KG6cf4z/ccc.gif
#8
C# while is similar to QM rep. Your code does not use rep.
#9
Still no output results.

Macro Macro5
Trigger Ax     Help - how to add the trigger to the macro
Code:
Copy      Help
out
UIA.CUIAutomation u._create
UIA.IUIAutomationElement t=u.GetFocusedElement; out t.CurrentClassName
UIA.IUIAutomationElement e
str ai
UIA.tagRECT r
UIA.IUIAutomationTreeWalker walker
int ct=t.CurrentControlType
if ct=5004
,walker=u.RawViewWalker
,rep
,,e=walker.GetFirstChildElement(t)
,,e=walker.GetNextSiblingElement(e)
,,ai=e.CurrentAutomationId 
,,ct=e.CurrentControlType
,,if find(ai "Caret")>=0 and ct=50025 ;;Contains("Caret"), Custom = 50025, Edit = 50004
,,,r=e.CurrentBoundingRectangle
,,,break
out "L: %iT: %iR: %iB: %i" r.left r.top r.right r.bottom
#10
https://chat.openai.com/share/008b220f-e...4e990c5684
#11
I still cannot get generic C# code to run in .NET Framework 4 and qm code.  I am indeed stuck with this issue ...
#12
Your QM code is almost complete. Just move two lines to other places.
#13
Thanks for your reminder, The issue has been resolved.

I just realized I was too careless.

In the code at #13,

5004 is incorrect; it should be changed to 50004, or else I will never succeed. Big Grin


Forum Jump:


Users browsing this thread: 5 Guest(s)