Jump to content
Sign in to follow this  
SvenP

COM Automation in AutoIt; no longer a myth.

Recommended Posts

I guys,

I hope I'm in the correct forum for this one.

I need some additional help concerning COM implementation in C++.

After spending some long nights with AutoIt (up to 3AM every night), I finally got some basic "Automation" working in AutoIT.

It is NOT supposed to replace VBScript or any other COM-enabled language, it is just to fill that tiny missing gap in AutoIT for controlling programs like Word or Excel.

(I didn't want do to it 'the other way around' using the AutoITX.dll :-)

After numerous cups of coffee, and MSDN-lookups, the following script lines DO ACTUALLY WORK in my modified AutoIt.exe:

; Excel Automation Example
; Based on AutoIt version 1.0.2
; Source code adapted by S.A.Pechler
; Beta version 16-01-2005

$MyObject = CreateObject("Excel.Application"); Create an Excel Object

if @error then 
    Msgbox (0,"","Error creating object!")
    exit(1)
endif

if IsObject($MyObject) then 
    Msgbox (0,"ExcelTest","You now successfully created an object in variable $MyObject.")
else
    Msgbox (0,"ExcelTest","I'm sorry, but creation of this object failed.")
    exit
endif

$MyObject.Visible = 1        ; Let the guy show himself
$MyObject.workbooks.add ; Add a new workbook

dim $i          ; Example: Fill some cells
dim $j

WITH $MyObject.activesheet
  for $i = 1 to 15
    for $j = 1 to 15
    .cells($i,$j).value = $i
    next
  next   
  
  Msgbox (0,"","Click to clear the cells")
  .range("A1:O15").clear

ENDWITH

$MyObject.activeworkbook.saved = 1; To prevent 'yes/no' questions from Excel
$MyObject.quit                       ; Get rid of him.

Msgbox (0,"ExcelTest","Is Excel gone now ?")
                ; Nope, only invisible, 
                ; but should be still in memory.
$MyObject = 0       ; Loose this object. (will call a reinit on the variant)

CloseObject()       ; Get rid of all objects.
                ; Excel will now be gone.
exit

HOWEVER: My knowledge about COM programming in C++ is very basic. The main issue is here that I don't know how to use LATE BINDING (!) to URL-style names like "WINNT://" or "WINMGMT://".

All documentation on the internet show only examples using EARLY binding.

I hope somebody can help me with that one, then my work is really finished.

IF somebody else is interested in adding COM functionality to AutoIt, I'll be happy to give you more details (about the new WITH statement, the new object-type variables, etc).

BUT I'm not sure if Jon wil agree in this, because formally he has 'secured' the source code to prevent code stealing. I was just lucky I got a copy of the 3.0.102 source code some time ago.

Jon, what's your opinion?

Regards,

-Sven 'the Geek'

Share this post


Link to post
Share on other sites

i hate OOP syntax :idiot::D but i think i sort of know what COM is now lol, but could someone just tell me what it really means? is it like the ability to work with other programs and sending commands to them or something??/ :lol:


FootbaG

Share this post


Link to post
Share on other sites

Larry,

Thanks for your suggestions.

I had already been thinking about that format. It has a few disadvantages:

1. If an object has a lot of sub-objects, you will end in very complex lines. The script would not be quite human-readable. In this case you can't shorten the lines with e.g. WITH statements.

2. Somehow you'll need to tell the function if its READ, PUT or METHOD.

3. AutoIt makes copies of each Variant when it enters a function. When you do that with Object-types then it will also create a new Object and destroy it after it exits the function.

4. Using function calls is much slower than using direct statements.

I created the extension mainly for use at my work. It saves me using a combination of both VBS and AutoIt to do certain automation tasks. Because of the same syntax, I could easily adapt existing VB scripts into AutoIT.

Regards,

-Sven

Share this post


Link to post
Share on other sites

...

I don't think Jon will like the $var.property syntax

...

Somehow, I think he will want functions, and avoid OOP syntax

If I am wrong, then it is I who really doesn't know Jon..

Lar.

<{POST_SNAPBACK}>

I don't see why that would be a problem.

If Sven is positive that the OOP syntax is faster than using functions, I don't understand why you still want to do it the hard way.

Edited by SlimShady

Share this post


Link to post
Share on other sites

I don't see why that would be a problem.

If Sven is positive that the OOP syntax is faster than using functions, I don't understand why you still want to do it the hard way.

<{POST_SNAPBACK}>

Just to satify Larry: My modified version is 100% backwards compatible to existing autoIt scripts. So you don't HAVE to use OOP if you don't want to.

That's why it took me a few days to find a solution that did not need modifications to the existing syntax. It's just a free-of-choice "extension" to the syntax.

BUT: I don't want to decide/discuss what is right/wrong to add to AutoIt.

It was just a project to satify my local needs. But I thought MAYBE others would be interested into it.

Regards,

-Sven

Edited by SvenP

Share this post


Link to post
Share on other sites

I like the original suggestion, it's just what I envisaged anyway (A VBScript type syntax, it's why . wasn't allowed in var names).

I've never used a WITH type thing though, not sure about that bit.

Valik, I know you've spent some time on COM support - not sure how far you got though as you were avoiding expectation setting :idiot:

Share this post


Link to post
Share on other sites

I am very excited to see your work..

I don't want to speak for Jon, but just a heads up on what you might find out.

I don't think Jon will like the $var.property syntax

you may end up with something like

Object($MyObject,"Visible",1)

If Object($MyObject) Then

Object($MyObject, "activesheet","cells",1,1,"value","test")

Somehow, I think he will want functions, and avoid OOP syntax

If I am wrong, then it is I who really doesn't know Jon..

In general for AutoIt, yeah you are right. But the COM stuff by it's nature needs to be accessed easily with methods and properties and I've always thought the VBscript method of doing it was a good one. AutoIt isn't OO but the COM objects are :idiot:

Share this post


Link to post
Share on other sites

Hello,

I did some more testing. It seems that the new code can even do more than I expected. I thought just Excel/Word Automation was all.

But look at this one:

; Wscript.Network Example
;
; Based on AutoIt version 1.0.2
;
; Source code adapted by S.A.Pechler
;
; Beta version 16-01-2005

$objNetwork = CreateObject("WScript.Network")

if not IsObject($objNetwork) then 
    Msgbox (0,"Wscript.network Test","I'm sorry, but creation of object $objNetwork failed.")
    exit
endif

$colDrives = $objNetwork.EnumNetworkDrives

if not IsObject($colDrives) then 
    Msgbox (0,"Wscript.network Test","I'm sorry, but creation of object $coldrives failed.")
    exit
endif

$NumDrives =  $colDrives.Count

if $NumDrives = 0 then
    Msgbox(0,"wscript.network", "You have currently no network drives")
else
    For $i = 0 to $colDrives.Count-1 Step 2
      Msgbox(0,"Wscript.network", "Drive letter: " & $colDrives.Item($i) & @TAB & " is mapped to: " & $colDrives.Item($i + 1))
     Next
endif

$coldrives=0
$objnetwork=0

CloseObject()

exit

I just copied this VBS example from the internet, changed the variable names to $...

..and it worked flawlessly. :-)

Where would this lead into when we combine the 3.103 GUI with these COM objects?

Hell, no one would use VBS anymore !!!

Regards,

-Sven

Share this post


Link to post
Share on other sites

3.0.103 will be out of date the instant it is released 

yep, theres going to be so much more stuff to add in :idiot:


FootbaG

Share this post


Link to post
Share on other sites

Jon, the progress I had made was minimal. I never really put any time into it or it would be done as it wasn't terribly hard (At least the basic call, get/set stuff).

Sven, does this support subscribing to events? I had envisioned something along the lines of subscribing to an event by registering a function to be called when that event is triggered.

Share this post


Link to post
Share on other sites

I usually don't get this excited, but I just have to say:

YIPEE!

This and stdio wil put autoit over the top functionwise. Thank you Sven. In the short time you have been here, you have added more to help autoit codewise and scriptwise than most anyone else in their first few posts.

Edited by this-is-me

Who else would I be?

Share this post


Link to post
Share on other sites

Jon, the progress I had made was minimal.  I never really put any time into it or it would be done as it wasn't terribly hard (At least the basic call, get/set stuff).

Sven, does this support subscribing to events?  I had envisioned something along the lines of subscribing to an event by registering a function to be called when that event is triggered.

<{POST_SNAPBACK}>

Hi Valik,

I only implemented the basic GET/PUT/METHOD calls. That was hard enough for me :-)

Maybe when this version is stable I could add subscribing.

Jon was very generous to send me the newest source, so I could look at the Hotkey() function how to pass a reference to a user function to receive the event.

I don't think I'll ever get this one finished...there's so much to add...

AutoIt programming has become a lifestyle..

Regards,

-Sven

Share this post


Link to post
Share on other sites

Ehm,

To keep up with my original question:

Who can help me with the GetObject() implementation?

Then I could start testing the beta with others.

If Jon agrees that I may distribute the modified .EXE

(NOT the AutoIT sourcecode ofcourse, Jon)

Regards,

-Sven

Share this post


Link to post
Share on other sites

Ehm,

To keep up with my original question: 

Who can help me with the GetObject() implementation?

Then I could start testing the beta with others.

If Jon agrees that I may distribute the modified .EXE

(NOT the AutoIT sourcecode ofcourse, Jon)

Regards,

-Sven

<{POST_SNAPBACK}>

What is the actual benefit of that "feature"? I've not seen that notation so I'm not familiar with exactly what its supposed to accomplish. If you could tell me what its for, then perhaps I could help.

Share this post


Link to post
Share on other sites

What is the actual benefit of that "feature"?  I've not seen that notation so I'm not familiar with exactly what its supposed to accomplish.  If you could tell me what its for, then perhaps I could help.

<{POST_SNAPBACK}>

Valik,

I'm trying to get rid of using two different scripting languages for my work.

Most things I can solve with AutoIt, but when I have to do hardware or network related scripting, then I can't get around VBS.

That's why I made this version of AutoIt which includes COM support. However, I still can't do the WINMGMT:// or WINNT:// stuff, because I can't get a correct CLSID lookup from these guys. (I need the correct CLSID to accomplish a GetActiveObject() call in C++).

Regards,

-Sven

EDIT: WINMGMT:// must be:WINMGMTS:// ofcourse.

Edited by SvenP

Share this post


Link to post
Share on other sites

You grade A++++ :idiot::D:lol:;)

THanks Sven for this outstanding contribution.

I don't know if we should violate the naming function convention <object><Verb><...>

But I like to have the Functions named ObjectCreate, ObjectGet, Object..., isObject

Share this post


Link to post
Share on other sites

You grade A++++ :graduated:  :graduated:  :graduated:  :graduated:

THanks Sven for this outstanding contribution.

I don't know if we should violate the naming function convention <object><Verb><...>

But I like to have the Functions named ObjectCreate, ObjectGet, Object..., isObject

<{POST_SNAPBACK}>

That's just an 'cosmetic' issue. Changing the name of a function call is no big deal in AutoIt, providing that you know the 'alphabet' (<- inside joke about only Jon can laugh :-).

BTW: Concerning my previous question in this topic; I think I've solved the problem with connecting to the WMI namespace. However I'm stuck with the FOR EACH xx in xx loop. I don't seem to be able to 'enumerate' objects from a 'collection' without using such loop structures.

Maybe I will implement that statement also..

This piece of code does actually work (using WINNT:// namespace):

; WINNT object Example
;
; Based on AutoIt version 1.0.3
;
; Source code adapted by S.A.Pechler
;
; Beta version 17-01-2005  01:08AM

;See also: http://msdn.microsoft.com/library/default.asp?url=/library/en-us/adsi/adsi/adsi_objects_of_winnt.asp


$MyCompName = @ComputerName

$oComputer=GetObject("WinNT://" & $MyCompName & ",computer" ) 

if not IsObject($oComputer) then 
    Msgbox (0,"","error creating object $oComputer.")
    exit
endif

$Classname= $oComputer.Class

If ($Classname = "Computer") Then

    MsgBox(0,"", "Computer owner: " & $oComputer.owner)
    MsgBox(0,"", "Computer division: " & $oComputer.Division)
    MsgBox(0,"", "Computer operatingSystem: " & $oComputer.OperatingSystem)
    MsgBox(0,"", "Computer operating System Version: " & $oComputer.OperatingSystemVersion)
    MsgBox(0,"", "Computer processor: " & $oComputer.Processor)
    MsgBox(0,"", "Computer processor Count: " & $oComputer.ProcessorCount)
EndIf

$oComputer=0

CloseObject()

exit

Regards,

-Sven

Share this post


Link to post
Share on other sites

Let me give you no code help but just encouragement. This is looking really really awesome. With WMI support I can get rid of my vbscript that I use to enum users.

Man autoIT is gettting me closer to never having to use an output file again. I love it. :idiot:

red

Share this post


Link to post
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
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...