Jump to content

Access AutoIt


trancexx
 Share

Recommended Posts

I am new in objects. can you please post a one example.Posted Image

It's really trivial. This maybe:

#include <AutoitObject.au3>

Opt("MustDeclareVars", 1)

; Object moniker
Global Const $sObjIdentifier = "DigisoulExampleIPC.Unique"

; Error monitoring
Global $oError = ObjEvent("AutoIt.Error", "_ErrFunc")
Func _ErrFunc()
;~  ConsoleWrite("COM Error, ScriptLine(" & $oError.scriptline & ") : Number 0x" & Hex($oError.number, 8) & " - " & $oError.windescription & @CRLF)
EndFunc

; Initialize AutoItObject
_AutoItObject_StartUp()

; Create object
Global $oObject = _IPCObject($sObjIdentifier)

; GUI for this demonstration
Global $hGui = GUICreate("AutoItObject IPC Example", 500, 500)
Global $hButtonSet = GUICtrlCreateButton("< Set shared IPCData >", 300, 100, 150, 30)
Global $hButtonRead = GUICtrlCreateButton("> Read shared IPCData <", 300, 350, 150, 30)
Global $hEditSet = GUICtrlCreateEdit("", 20, 20, 250, 200)
Global $hEditRead = GUICtrlCreateEdit("", 20, 270, 250, 200)
GUISetState()

While 1
    Switch GUIGetMsg()
        Case -3
            Exit
        Case $hButtonSet
            $oObject.IPCData = GUICtrlRead($hEditSet)
        Case $hButtonRead
            GUICtrlSetData($hEditRead, $oObject.IPCData)
    EndSwitch
WEnd



;****************************************************************
;****************************************************************
Func _IPCObject($sID)
    ; First try to get object from ROT
    Local $oObj = ObjGet($sID)
    If IsObj($oObj) Then Return $oObj ; OK!
    ; If that failed then create object from scratch
    $oObj = _MakeIPCObject()
    ; Register (publish) created object
    _AutoItObject_RegisterObject($oObj, $sID)
    Return $oObj ; return it
EndFunc

; Define object
Func _MakeIPCObject()
    Local $oClassObject = _AutoItObject_Class()
    $oClassObject.AddProperty("IPCData") ; adding just one property
    Return $oClassObject.Object ; here's the object
EndFunc   ;==>_SomeObject
;****************************************************************
;****************************************************************

Run as many instances of that script, they will all share the same variable (object property). Share as have read/write access.

First script that creates the object owns it (server). When that script exits there is object no more.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

This likely a no-brainer but forgive me please for getting carried away. I very recently started learning Javascript and have investigated jsc.exe. I am impressed by this application of Autoit (and , indeed I should emphasise AutoIt) and would like to create (in the future) standalone exes (if possible) either in a language like javascript or in Autoit (or both (oh, get to the point man!) that make muliti-script language usage.

How would I accomplish this? The key being to start the server and kill the server on exit.

TIA

Link to comment
Share on other sites

This likely a no-brainer but forgive me please for getting carried away. I very recently started learning Javascript and have investigated jsc.exe. I am impressed by this application of Autoit (and , indeed I should emphasise AutoIt) and would like to create (in the future) standalone exes (if possible) either in a language like javascript or in Autoit (or both (oh, get to the point man!) that make muliti-script language usage.

How would I accomplish this? The key being to start the server and kill the server on exit.

TIA

Start server from other script? Is that it?

If it is then if you want it to work on systems without AutoIt installed, compile the server and add function to run it from that other (vbs, js, whatever) script. If you don't know how to Run executables using those languages then... learn.

Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Hi trancexx,

"Line:6, Column:1, Error:(null), Code:800401E4, Source:(null)"

3. Set WshShell = WScript.CreateObject("WScript.Shell")

4. WshShell.Run "h:\AutoItServer.exe"

5.

6. Set oAutoIt = GetObject("AutoIt.Application") ' the magic

Falls over for me at Line 6.(?)

Does there need to be a pause or return code from WshShell.Run?

Link to comment
Share on other sites

Hi trancexx,

"Line:6, Column:1, Error:(null), Code:800401E4, Source:(null)"

3. Set WshShell = WScript.CreateObject("WScript.Shell")

4. WshShell.Run "h:\AutoItServer.exe"

5.

6. Set oAutoIt = GetObject("AutoIt.Application") ' the magic

Falls over for me at Line 6.(?)

Does there need to be a pause or return code from WshShell.Run?

Yes, you need to give AutoIt enough time to initialize, start interpreting process and all other script stuff.

Set oAutoIt = GetROTObject("AutoItServer.exe", "AutoIt.Application")
'...


Function GetROTObject(sServer, sCLSID)
    iTimeout = 3000 ' default timeout in ms
    On Error Resume Next
    Set oObject = GetObject(sCLSID)
    If Not IsObject(oObject) Then
        Set oWShell = WScript.CreateObject("WScript.Shell")
        oWShell.Run """" & sServer &  """ /StartServer"

        For i = 0 To iTimeout/10
            Set oObject = GetObject(sCLSID)
            If IsObject(oObject) Then Exit For
            Wscript.Sleep(10)
        Next

        If Not IsObject(oObject) Then oWShell.Run "taskkill /f /im " & """" & sServer & """", 0, True
    End If

    Set GetROTObject = oObject
End Function
Edited by trancexx

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Why does this work:

Global $sMyCLSID = "AutoIt.Application"
Global $hObj = _AutoItObject_RegisterObject($oObject, $sMyCLSID)
ConsoleWrite($hObj & @CRLF)

But not this?

Global $sMyCLSID = "ShiftERZipServer.Application"
Global $hObj = _AutoItObject_RegisterObject($oObject, $sMyCLSID)
ConsoleWrite($hObj & @CRLF)

This works so it's not about the length

Global $sMyCLSID = "AutoItjhhhhhhhhhhhhhhhhhhhhhhhh.Applicationggggggggggggggggg"
Global $hObj = _AutoItObject_RegisterObject($oObject, $sMyCLSID)
ConsoleWrite($hObj & @CRLF)

:huh2:

Link to comment
Share on other sites

Why does this work:

Global $sMyCLSID = "AutoIt.Application"
Global $hObj = _AutoItObject_RegisterObject($oObject, $sMyCLSID)
ConsoleWrite($hObj & @CRLF)

But not this?

Global $sMyCLSID = "ShiftERZipServer.Application"
Global $hObj = _AutoItObject_RegisterObject($oObject, $sMyCLSID)
ConsoleWrite($hObj & @CRLF)

This works so it's not about the length

Global $sMyCLSID = "AutoItjhhhhhhhhhhhhhhhhhhhhhhhh.Applicationggggggggggggggggg"
Global $hObj = _AutoItObject_RegisterObject($oObject, $sMyCLSID)
ConsoleWrite($hObj & @CRLF)

:huh2:

Are you sure there isn't server already running? Check that.

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

Are you sure there isn't server already running? Check that.

You are right, the server was already running. Can't understand how I missed it, I actually had Task Manager opened when working on it!

:huh2:

Link to comment
Share on other sites

I just saw your (new?) member title or whatever that's called. ;)

Funny guy.

I've been "uncloaked" for almost two months now, I think you need to recalibrate your sensors! :huh2:
Link to comment
Share on other sites

Inline ASM in AutoIt x64 is hard before, now _AutoItObject_RegisterObject sovle this problem.

AutoItServer + FASMObject = Inline ASM in AutoIt x64

I will use this idea and update FASM UDF as soon as possible

Thanks, trancexx!

新版 _ArrayAdd 的白痴作者,不管是誰,去死一死好了

 

Link to comment
Share on other sites

  • 7 months later...
  • 2 years later...

Of course. If you don't mind vanilla flavor:

MULTI_QI qiResult[1] = { { &IID_IDispatch, nullptr, S_OK } };
OLECHAR* moniker = L"AutoIt.Application";
HRESULT hr = ::CoGetInstanceFromFile(nullptr, nullptr, nullptr, CLSCTX_SERVER, STGM_READWRITE, moniker, 1, qiResult);

if (SUCCEEDED(hr))
{
    IDispatch* pDisp = reinterpret_cast<IDispatch*>(qiResult[0].pItf);
    OLECHAR* meth = L"Call";
    DISPID dispID = 0;
    hr = pDisp->GetIDsOfNames(IID_NULL, &meth, 1, LOCALE_SYSTEM_DEFAULT, &dispID);
    if (SUCCEEDED(hr))
    {
        // Invoking function Beep(500, 700)
        // That means there are three arguments: string "Beep", integer 500 and integer 700
        // COM args are backward (first is last and vice versa)
        VARIANT pArgs[3];

        // Last argument is integer 700
        ::VariantInit(&pArgs[0]);
        pArgs[0].vt = VT_INT;
        pArgs[0].intVal = 700;

        // Second one is integer 500
        ::VariantInit(&pArgs[1]);
        pArgs[1].vt = VT_INT;
        pArgs[1].intVal = 500;

        // And first one is string "Beep"
        ::VariantInit(&pArgs[2]);
        pArgs[2].vt = VT_BSTR;
        pArgs[2].bstrVal = ::SysAllocString(L"Beep");


        EXCEPINFO ExcepInfo = {}; // error information if exception occures (initialized)
        UINT uiArgErr; // index of argument that causes possible error

        DISPPARAMS dp = {}; // structure required for passing arguments (initialized)
        // Build DISPPARAMS from the created array of VARIANT-s
        dp.cArgs = 3; // three arguments
        dp.rgvarg = pArgs; // array pointer

        // To collect the result to
        VARIANT vResult;
        ::VariantInit(&vResult);

        hr = pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_METHOD, &dp, &vResult, &ExcepInfo, &uiArgErr);

        // Clear VARIANTs (this will free strings too)
        ::VariantClear(&pArgs[0]);
        ::VariantClear(&pArgs[1]);
        ::VariantClear(&pArgs[2]);

        // ALL DONE!
    }
}

That's the same as:

$oObj = ObjGet("AutoIt.Application")

$oObj.Call("Beep", 500, 700);

♡♡♡

.

eMyvnE

Link to comment
Share on other sites

I have an assignment which i need to design an application for a business in c# which i currently am unfamiliar with... does this mean that using that, i could potentially write a script in c# which uses autoit functions, includes etc (that i am familiar with) 

Little confused..  any chance it can be explained in lamens terms? without getting flamed for being a noob lol :(

Link to comment
Share on other sites

  • 1 year later...

Anyone tried this with SQL Server?

I tried to run this script

DECLARE @intResult INT
DECLARE @comHandle INT
DECLARE @sin float

EXEC @intResult = sp_OACreate 'AutoIt.Application', @comHandle OUTPUT, 5
select @intResult, @comHandle
EXEC @intResult = sp_OAMethod @comHandle,'Call',@sin OUTPUT,'Sin',254
select @intResult
EXEC sp_OADestroy @comHandle

select @sin

but sp_OACreate fail to create an instance with error code -2147221005 (invalid object name). I'm not sure if it's the SQL who doesn't have enough privileges to create the instance or if AutoIt server is not visible from SQL Server.

When the words fail... music speaks.

Link to comment
Share on other sites

I don't know SQL but that has the word "Create" a bunch of times. Are you sure that function corresponds to what in AutoIt would be ObjGet() and not like the more similar sounding ObjCreate()?

Also did you have your server script running when you ran that?

Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...