Jump to content

How To Choose An Action Based On Window Contents


Recommended Posts

Hey all. I'm VERY new to AutoIT, but I've scripted for years in various languages. If there's one thing I'ved learned, it's Garbage-In, Garbage-Out, which seems to be the case all too often since computers have a habit of doing EXACTLY what you tell them to, but we tend to expect intuition where there isn't anyway.

Anyway, I've got a very basic question I'm sure many of you can answer, but bear with me as I've already gone through example scripts and the help files.

I'm basically writing a script to add a new ODBC driver. Yes, I'm using the GUI. Yes, I know this is a bad idea. No, I'm not going to do it any other way, so don't bother suggesting that.

The problem is this: when adding a new System DSN entry I'm counting on a Showcase driver to already exist in the list of drivers available to me. Now when it's there things work great, but when it's missing I run into problems, specifically when I send the keystroke 'Showcase' to the GUI the closest thing ODBC can come up with is SQL Server. As a result, for PCs without the Showcase driver I end up in a SQL Server window instead.

Of course, all my keystrokes after that are shot since the options are all different and I'm counting on there being X number of fields with Y number of keystrokes.

Since there doesn't seem to be any way for AutoIT to detect which entries do/don't appear in the list of available drivers, I've been tossing the keystroke 'Showcase' out there and proceding on to the next step. What I need is for AutoIT to then examine the open window and determine if there is specific Showcase text present, versus anything else. Then, if the text is there, the assumption is the Showcase driver is present and was selected, and the script can continue as normal. However, if the text is not there, then it's a safe bet the Showcase driver isn't present and I'm really sitting in a SQL window instead, at which point I want the script to abort.

However, I can't find any way to tell AutoIT "Look for the phrase XXXXXXX in the open window, and if you find it proceed, but if you don't, abort".

Any ideas?

BTW, my script is offensively basic, with the following steps being used to open the ODBC administrator, move to the System DSN tab, attempt to slect the Showcase entry (if one exists), and then open the driver window itself:

==================================================

Run("odbcad32.exe")

WinWaitActive("ODBC Data Source Administrator", "An ODBC User")

Send("{TAB}")

Send("{TAB}")

Send("{TAB}")

Send("{TAB}")

Send("{TAB}")

Send("{TAB}")

Send("{TAB}")

Send("{RIGHT}")

Send("{TAB}")

Send("{TAB}")

Send("{SPACE}")

WinWaitActive("Create New Data Source", "Select a driver for which")

Send("{Showcase}")

Send("{TAB}")

Send("{SPACE}")

==================================================

Thanks in advance!

-Bob

PS: Seriously, don't bother suggesting an alternate way of doing this. It's not that I'm not interested, but I specifically used this example because the same problem may come up with many other scripts in which I want the script to make a split-second decision based on what is in the active window at that moment in time.

Link to comment
Share on other sites

If StringInStr(WinGetText("my app name"), "Showcase") Then
;do Showcase action
Else
;do something else
EndIf

:)

Hey, thanks for the quick reply. But that only partially makes sense to me.

I don't know the name of the new window because the name is based on the type of driver, so the WinGetText function won't work for me.

I did a little more research, and I can THINK I can store the name of the active window in a variable, and then use the variable int he StringInStr function (not 100% sure yet), but even that won't work because first I need to tell AutoIT to wait for the next active window to pop up and a WinWaitActive command requires that I provide specific info on the new window, but again, I don't have that info because I don't know what window will appear.

Thanks again,

Bob

Link to comment
Share on other sites

I guess you "do know" what window will appear because it is you who is installing that application :)

You will need to find something which can uniquely identify the windows (so you can't make mistakes), a pattern in the title of these windows, some text inside the window ... anything what can "give a clue" to your AutoIt script.

Unfortunately you can't get help with that part (because it is you who has the application and can experiment with) and you'll have to do it yourself. It is not easy (it can become frustrating sometimes) but it is a challenge. You "look like" you like writing scripts (IMO lol) so this challenge will offer some excitement :)

Seriously: welcome to the real scripting world, where you have to do your homework. This is what scripting is about.

Try to solve your problem and you will feel great when you'll find the solution.

suggestion: WinTitleMatchMode will be your friend ;)

Good luck,

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

Link to comment
Share on other sites

I'm not sure, but basically you need to know if the correct window is showing, right?

So, it means you need something to filter the correct windows. Is there any pattern that the correct window always use?

Maybe different class, specific text (ex: driver: 0x00), or specific buttons. From this pattern, you could create a script that would filter the correct windows.

My suggestion is to use AutoIt Window Information, Au3Info.exe if I'm not mistaken. Using that tool, user is able to check on a window and its components.

Link to comment
Share on other sites

... but even that won't work because first I need to tell AutoIT to wait for the next active window to pop up and a WinWaitActive command requires that I provide specific info on the new window, but again, I don't have that info because I don't know what window will appear. ...

Then use WinWaitNotActive to wait for some other window to come up.

AutoItSetOption("TrayIconDebug", 1) ;0-off

Run("odbcad32.exe")
WinWaitActive("ODBC Data Source Administrator", "An ODBC User")

ControlCommand("ODBC Data Source Administrator", "An ODBC User", "SysTabControl321", "TabRight", "")
WinWaitActive("ODBC Data Source Administrator", "An ODBC System")

ControlClick("ODBC Data Source Administrator", "An ODBC System", "Button1") ; add button
WinWaitActive("Create New Data Source", "Select a driver for which")

ControlSend("Create New Data Source", "Select a driver for which", "SysListView321", "Microsoft ODBC Driver for Oracle")
ControlClick("Create New Data Source", "Select a driver for which", "Button4") ; finish button
WinWaitNotActive("Create New Data Source", "Select a driver for which")

If WinGetTitle("") <> "Desired Title" Then
    ;do stuff
Else
    ;do other stuff
EndIf

[size="1"][font="Arial"].[u].[/u][/font][/size]

Link to comment
Share on other sites

Argh...

Okay, I'm seriously trying over and over again to get this to work, but so far I'm missing the mark.

The problem, as simply as I can put it, is this: if I don't know the name of the window that will appear, how do I tell my script to wait for the window to appear?

Now it is true that to a limited extent I do know the name of the window, but only insofar as there are two possibilities: a window named 'ShowCase iSeries Driver' (there's technically another variation but let's assume that's the one) and a window named 'Create a New Data Source to SQL Server'.

Once I send my ControlSend command with the first part of the driver name I wish to add, in this case 'ShowCase', and I send the corresponding ControlClick to proceed to the 'unknown' window, I'm stumped. I can't tell AutoIT to push blindly forward because sometimes it takes a few seconds for the new window to appear. So I have to tell it to wait, but if I don't know which window will appear then how can I tell it to wait - it won't know what it's waiting for.

I don't really understand the concept of WinWaitNotActive either. What's the point in telling the script to wait for a completely unrelated (possibly non-existent) window to show up? How will that benefit me?

Oh, and thanks for all the help, guys. I'm not looking for handouts here, but as great as the documentation in the program is, it doesn't cover everything, and I consider this a fairly basic thing (already run into two scripts which require it, and I'm not doing anything fancy).

Any additional help is appreciated.

Thanks,

Bob

Link to comment
Share on other sites

Okay, got past the last problem. Turned out that by using WinWaitNotActive and putting in the title value of the previous window I was able to tell AutoIT to wait for whatever window showed up next, and from there pull info on the title and run a simple If/Then operation.

So that's good. Only problem now is that because I'm wrapped up in If/Thens I'm forced to use functions (to ensure all executes in the right order). Unfortunately, I'm stuck on another very basic detail: not sure how to tell AutoIT to actually run a function I've created.

Here's a sample of my script as-is, for your review (special thanks to herewasplato for the inspiration...I actually created the control commands from scratch but used your notes as a guide [ie: not cut and paste]):

=============================================

Run("odbcad32.exe")

WinWaitActive("ODBC Data Source Administrator", "An ODBC User")

ControlCommand("ODBC Data Source Administrator", "An ODBC User", "SysTabControl321", "TabRight", "")

WinWaitActive("ODBC Data Source Administrator", "An ODBC System")

ControlClick("ODBC Data Source Administrator", "An ODBC System", "Button1")

WinWaitActive("Create New Data Source", "Select a driver for which")

ControlSend("Create New Data Source", "Select a driver for which", "SysListView321", "ShowCase")

ControlClick("Create New Data Source", "Select a driver for which", "Button4")

WinWaitNotActive("ODBC Data Source Administrator","An ODBC System") ; Wait for the last active window to no longer be active

$win = WinGetTitle("")

If $win == "ShowCase iSeries Driver" Then

MyFuncA

ElseIf $win == "ShowCase ODBC Setup" Then

MyFuncA

Else

MyFuncZ

EndIf

func MyFuncA() ; Create a new System DSN entry

Send("****REMOVED FOR SECURITY REASONS****")

Send("{TAB}")

Send("{TAB}")

Send("****REMOVED FOR SECURITY REASONS****")

Send("{TAB}")

Send("{TAB}")

Send("{TAB}")

$win2 = WinGetTitle("") ; Get the title of the active window

Send("{SPACE}")

WinWaitNotActive($win2) ; Wait for the last active window to no longer be active

$win3 = WinGetTitle("") ; Get the title of the active window

If $win3 == "ShowCase iSeries Driver Configuration" Then

MyFuncB

ElseIf $win3 == "ShowCase ODBC" Then

MyFuncB

Else

MyFuncC

EndIf

EndFunc

func MyFuncB() ; Confirm Driver Entry Overwrite

Send("{SPACE}")

MyFuncC

EndFunc

func MyFuncC() ; Close the ODBC Data Source Administrator

WinWaitActive("ODBC Data Source Administrator", "An ODBC System")

ControlClick("ODBC Data Source Administrator", "An ODBC System", "Button5")

Exit

EndFunc

func MyFuncZ() ; Abort the script

Send("{ESC}")

Send("{ESC}")

Exit

EndFunc

=============================================

Hopefully this makes sense, but if not, here's the summary:

- ODBC administrator is launched, and a bunch of control commands are executed

- I tell AutoIT to wait until the currently active window is no longer active

- I record the name of the new active window in a string called $win

- I perform an If/Then, instructing AutoIT that if the new window's title matches either of the two correct titles to jump to a function I've called MyFuncA. Otherwise, I instruct it to jump to MyFuncZ, which essentially backs out of the ODBC admin and exist the script.

- MyFuncA launches, populating the window with important data, then closes the window. Before closing I record the window's title into the string $win2.

- Again I wait for the active window to no longer be active, then record the title of the new active window, this time into a string called $win3.

- Perform another If/Then, this time in an effort to determine if the old entry is going to be overwritten by a new entry. If the overwrite window is active I tell the script to jump to MyFuncB, and then proceed to MyFuncC to close the ODBC Administrator and end the script. If the overwrite window is not active then I assume there was no overwrite prompt and just jump straight to MyFuncC to close the ODBC Administrator and end the script.

I think this should work, at least in theory. I'm sure I could have nested more functions, but all the AutoIT help file examples only show a single command in the If/Then lines, suggesting that I have to create full functions every time I want to perform more than one action as the result of an If/Then (don't know this for sure, but didn't see the harm in doing it this way).

Soooo...after all that, which hopefully proves I'm actually trying to make this work and wracking my brain here, the only problem is that I get syntax errors on the lines which launch the functions. I'm not sure if I have to prefix my user functions with a unique command (like GO, RUN, DO, etc...), but so far nothing I've tried works.

Thoughts?

Thanks again, for the (hopefully) last time!

-Bob

Link to comment
Share on other sites

You've got pretty much the part of calling your functions but you have to add () after the function name:

If $win == "ShowCase iSeries Driver" Then
MyFuncA()
ElseIf $win == "ShowCase ODBC Setup" Then
MyFuncA()
Else
MyFuncZ()
EndIf

SNMP_UDF ... for SNMPv1 and v2c so far, GetBulk and a new example script

wannabe "Unbeatable" Tic-Tac-Toe

Paper-Scissor-Rock ... try to beat it anyway :)

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...