-
Posts
25 -
Joined
-
Last visited
Everything posted by tfabris
-
IUIAutomation MS framework automate chrome, FF, IE, ....
tfabris replied to junkew's topic in AutoIt Example Scripts
Never mind. The solution is that I must not depend on the "UIA_V0_4" as being the latest. Instead I must download the that, PLUS the latest "UIA_WIP*" work in progress file and unzip that as well. After that it runs. -
IUIAutomation MS framework automate chrome, FF, IE, ....
tfabris replied to junkew's topic in AutoIt Example Scripts
Junkew, I am encountering a problem with this test framework. It fails to run and gets an error in the script code. I tried to follow the Quickstart steps listed here: Here is exactly what I did: - Downloaded and unzipped "UIA_V0_4" from the top post in this thread: http://www.autoitscript.com/forum/index.php?app=core&module=attach§ion=attach&attach_id=44102 - Downloaded "simplespy.AU3" from the top post in this thread: http://www.autoitscript.com/forum/index.php?app=core&module=attach§ion=attach&attach_id=44661 - Placed the downloaded simplespy into the same folder as the unzipped files from "UIA_V0_4". - Double-clicked on simplespy which opens it in my SCITE script editor. - Pressed the F5 key in the script editor to run the script. Result: >"C:Program Files (x86)AutoIt3SciTE..autoit3.exe" /ErrorStdOut "C:TempUIA_V0_4simplespy.au3" "C:TempUIA_V0_4UIAWrappers.au3" (150) : ==> Variable used without being declared.: $sections=IniReadSectionNames($strFName) ^ ERROR >Exit code: 1 Time: 0.309 Can you help me figure out how to get this running? -
Simplespy puts out 218;290 for the bounding rectangle of the object I'm after. However I think those were absolute screen coordinates, not window-relative coordinates, and I don't see the window's screen position in the output so I don't know where to do the math to get the window-relative coordinates in this case. Here is the full output: Mouse position is retrieved 279-300 At least we have an element [Show details][] Having the following values for all properties: Title is: <Show details> Class := <> controltype:= <UIA_HyperlinkControlTypeId> ,<50005> , (0000C355) *** Parent Information top down *** 7: Title is: <Desktop> Class := <#32769> controltype:= <UIA_PaneControlTypeId> ,<50033> , (0000C371) "Title:=Desktop;controltype:=UIA_PaneControlTypeId;class:=#32769" 6: Title is: <Diagnostic Report> Class := <WindowsForms10.Window.8.app.0.33c0d9d> controltype:= <UIA_WindowControlTypeId> ,<50032> , (0000C370) "Title:=Diagnostic Report;controltype:=UIA_WindowControlTypeId;class:=WindowsForms10.Window.8.app.0.33c0d9d" 5: Title is: <> Class := <WindowsForms10.Window.8.app.0.33c0d9d> controltype:= <UIA_PaneControlTypeId> ,<50033> , (0000C371) "Title:=;controltype:=UIA_PaneControlTypeId;class:=WindowsForms10.Window.8.app.0.33c0d9d" 4: Title is: <> Class := <WindowsForms10.Window.8.app.0.33c0d9d> controltype:= <UIA_PaneControlTypeId> ,<50033> , (0000C371) "Title:=;controltype:=UIA_PaneControlTypeId;class:=WindowsForms10.Window.8.app.0.33c0d9d" 3: Title is: <> Class := <WindowsForms10.Window.8.app.0.33c0d9d> controltype:= <UIA_PaneControlTypeId> ,<50033> , (0000C371) "Title:=;controltype:=UIA_PaneControlTypeId;class:=WindowsForms10.Window.8.app.0.33c0d9d" 2: Title is: <> Class := <WindowsForms10.Window.8.app.0.33c0d9d> controltype:= <UIA_PaneControlTypeId> ,<50033> , (0000C371) "Title:=;controltype:=UIA_PaneControlTypeId;class:=WindowsForms10.Window.8.app.0.33c0d9d" 1: Title is: <Status> Class := <WindowsForms10.Window.8.app.0.33c0d9d> controltype:= <UIA_PaneControlTypeId> ,<50033> , (0000C371) "Title:=Status;controltype:=UIA_PaneControlTypeId;class:=WindowsForms10.Window.8.app.0.33c0d9d" 0: Title is: <Show details> Class := <WindowsForms10.STATIC.app.0.33c0d9d> controltype:= <UIA_TextControlTypeId> ,<50020> , (0000C364) "Title:=Show details;controltype:=UIA_TextControlTypeId;class:=WindowsForms10.STATIC.app.0.33c0d9d" *** Standard code *** #include "UIAWrappers.au3" AutoItSetOption("MustDeclareVars", 1) Local $oP6=_UIA_getObjectByFindAll($UIA_oDesktop, "Title:=Diagnostic Report;controltype:=UIA_WindowControlTypeId;class:=WindowsForms10.Window.8.app.0.33c0d9d", $treescope_children) _UIA_Action($oP6,"setfocus") Local $oP5=_UIA_getObjectByFindAll($oP6, "Title:=;controltype:=UIA_PaneControlTypeId;class:=WindowsForms10.Window.8.app.0.33c0d9d", $treescope_children) _UIA_Action($oP5,"setfocus") Local $oP4=_UIA_getObjectByFindAll($oP5, "Title:=;controltype:=UIA_PaneControlTypeId;class:=WindowsForms10.Window.8.app.0.33c0d9d", $treescope_children) _UIA_Action($oP4,"setfocus") Local $oP3=_UIA_getObjectByFindAll($oP4, "Title:=;controltype:=UIA_PaneControlTypeId;class:=WindowsForms10.Window.8.app.0.33c0d9d", $treescope_children) _UIA_Action($oP3,"setfocus") Local $oP2=_UIA_getObjectByFindAll($oP3, "Title:=;controltype:=UIA_PaneControlTypeId;class:=WindowsForms10.Window.8.app.0.33c0d9d", $treescope_children) _UIA_Action($oP2,"setfocus") Local $oP1=_UIA_getObjectByFindAll($oP2, "Title:=Status;controltype:=UIA_PaneControlTypeId;class:=WindowsForms10.Window.8.app.0.33c0d9d", $treescope_children) _UIA_Action($oP1,"setfocus") Local $oP0=_UIA_getObjectByFindAll($oP1, "Title:=Show details;controltype:=UIA_TextControlTypeId;class:=WindowsForms10.STATIC.app.0.33c0d9d", $treescope_children) _UIA_Action($oP0,"setfocus") ;~ First find the object in the parent before you can do something ;~$oUIElement=_UIA_getObjectByFindAll("Showdetails.mainwindow", "title:=Show details;ControlType:=UIA_HyperlinkControlTypeId", $treescope_subtree) Local $oUIElement=_UIA_getObjectByFindAll($oP0, "title:=Show details;ControlType:=UIA_HyperlinkControlTypeId", $treescope_subtree) _UIA_action($oUIElement,"click") *** Detailed properties of the highlighted element *** UIA_title:= <Show details> UIA_iaccessiblevalue:= <Show details> UIA_iaccessiblechildId:= <0> UIA_BoundingRectangle:= <218;290;76;16> UIA_ProcessId:= <6756> UIA_ControlType:= <50005> UIA_LocalizedControlType:= <hyperlink> UIA_Name:= <Show details> UIA_HasKeyboardFocus:= <False> UIA_IsKeyboardFocusable:= <True> UIA_IsEnabled:= <True> UIA_Culture:= <0> UIA_IsControlElement:= <True> UIA_IsContentElement:= <True> UIA_IsPassword:= <False> UIA_NativeWindowHandle:= <0> UIA_IsOffscreen:= <False> UIA_Orientation:= <0> UIA_IsRequiredForForm:= <False> UIA_IsDockPatternAvailable:= <False> UIA_IsExpandCollapsePatternAvailable:= <False> UIA_IsGridItemPatternAvailable:= <False> UIA_IsGridPatternAvailable:= <False> UIA_IsInvokePatternAvailable:= <True> UIA_IsMultipleViewPatternAvailable:= <False> UIA_IsRangeValuePatternAvailable:= <False> UIA_IsScrollPatternAvailable:= <False> UIA_IsScrollItemPatternAvailable:= <False> UIA_IsSelectionItemPatternAvailable:= <False> UIA_IsSelectionPatternAvailable:= <False> UIA_IsTablePatternAvailable:= <False> UIA_IsTableItemPatternAvailable:= <False> UIA_IsTextPatternAvailable:= <False> UIA_IsTogglePatternAvailable:= <False> UIA_IsTransformPatternAvailable:= <False> UIA_IsValuePatternAvailable:= <True> UIA_IsWindowPatternAvailable:= <False> UIA_ValueValue:= <Show details> UIA_ValueIsReadOnly:= <False> UIA_RangeValueValue:= <0> UIA_RangeValueIsReadOnly:= <True> UIA_RangeValueMinimum:= <0> UIA_RangeValueMaximum:= <0> UIA_RangeValueLargeChange:= <0> UIA_RangeValueSmallChange:= <0> UIA_ScrollHorizontalScrollPercent:= <0> UIA_ScrollHorizontalViewSize:= <100> UIA_ScrollVerticalScrollPercent:= <0> UIA_ScrollVerticalViewSize:= <100> UIA_ScrollHorizontallyScrollable:= <False> UIA_ScrollVerticallyScrollable:= <False> UIA_SelectionCanSelectMultiple:= <False> UIA_SelectionIsSelectionRequired:= <False> UIA_GridRowCount:= <0> UIA_GridColumnCount:= <0> UIA_GridItemRow:= <0> UIA_GridItemColumn:= <0> UIA_GridItemRowSpan:= <1> UIA_GridItemColumnSpan:= <1> UIA_DockDockPosition:= <5> UIA_ExpandCollapseExpandCollapseState:= <3> UIA_MultipleViewCurrentView:= <0> UIA_WindowCanMaximize:= <False> UIA_WindowCanMinimize:= <False> UIA_WindowWindowVisualState:= <0> UIA_WindowWindowInteractionState:= <0> UIA_WindowIsModal:= <False> UIA_WindowIsTopmost:= <False> UIA_SelectionItemIsSelected:= <False> UIA_TableRowOrColumnMajor:= <2> UIA_ToggleToggleState:= <2> UIA_TransformCanMove:= <False> UIA_TransformCanResize:= <False> UIA_TransformCanRotate:= <False> UIA_IsLegacyIAccessiblePatternAvailable:= <True> UIA_LegacyIAccessibleChildId:= <0> UIA_LegacyIAccessibleName:= <Show details> UIA_LegacyIAccessibleValue:= <Show details> UIA_LegacyIAccessibleRole:= <30> UIA_LegacyIAccessibleState:= <1048576> UIA_LegacyIAccessibleDefaultAction:= <Click> UIA_IsDataValidForForm:= <False> UIA_ProviderDescription:= <[pid:6756,hwnd:0x0 Main(parent link):Microsoft: MSAA Proxy (unmanaged:uiautomationcore.dll)]> UIA_IsItemContainerPatternAvailable:= <False> UIA_IsVirtualizedItemPatternAvailable:= <False> UIA_IsSynchronizedInputPatternAvailable:= <False>
-
I could not find a WinGetSize function so I used the width and height of WinGetPos instead, I'm hoping that's what you meant. Note that in this run, I show a screen shot where the window I'm working with is a different position and size than I showed in my last example. But I get the same basic problem (and the same answers) no matter what size or position the window occupies on the screen. Updated screen shot and code: $ControlCoordinates = ControlGetPos("Diagnostic Report", "", "[TEXT:Show details]") $WinGetClientSize = WinGetClientSize("Diagnostic Report") $WinGetPos = WinGetPos("Diagnostic Report") MsgBox(0, "Output from my AutoIt Test Script", "Autoit code believes the control to be at this location: " & @CRLF & $ControlCoordinates[0] & "," & $ControlCoordinates[1] & @CRLF & @CRLF & $WinGetClientSize[0] & "," & $WinGetClientSize[1] & "<- Client Size" & @CRLF & $WinGetPos[2] & "," & $WinGetPos[3] & "<- Get Pos") WinActivate("Diagnostic Report") Opt("MouseCoordMode", 0) ; This is actually WORSE if I do window-relative (0) instead of client-area-relative (2). MouseMove ($ControlCoordinates[0], $ControlCoordinates[1], 0) The difference in the Y direction betwen WinGetClientSize and WinGetPos is 45. This difference is the same no matter where on the screen the window is, or what size it is, when I run it, the difference is always 45. Not sure if that's relevant though. For example, if I add the code in (shown above now) to move the mouse to the upper left corner of that control, if I do it Window-relative (MouseCoordMode =0) instead of ClientArea-relative (MouseCoordMode =2), then it's actually WORSE that way, with the pointer being even higher up on the screen than it should be. Interesting note!: I just got done writing a bunch of C# code which tried to do the same thing using the API functions GetWindowRect and MapWindowPoints. Guess what? That code got the same answer as the AutoIt script got! In other words, the wrong answer of 116,140. So what is AU3INFO doing that's special, that gets the answer more right than either AutoIt or GetWindowRect/MapWindowPoints? EDIT: Updated information: This seems to be related to the number of lines of text which appear in the box along with the "Show details" link. (The example screen I have shown can have different numbers of lines of summary text in the box before the link I'm trying to click on.) If there are more lines of text in the box, then the error between where it should be clicking and where it is clicking, is even greater.
-
Also, I can tell it is not messing up based on the windows title bar size. If it were, the number would be in the 200s, not 164 or 140. For instance, if a take the screen shot and crop it down to just the client area rectangle of the window, then the control sits pretty much exactly at 116,164 as AU3INFO says it should.
-
Please help! I am using Autoit version 3.3.10.2 to automate a task where I need to click on a control on a window of a third party program. I am having a problem with the ControlGetPos function. When I call it with the correct information about the contol and its parent window, it reports the wrong value for the Y position, though the X position is correct. When I run AU3INFO.EXE it reports the correct position, though. Please see the attached screen shot to understand what I mean. Here is the source code for the example code that I am running in the attached screen shot. These are the only two lines in my example program, for simplicity (it assumes the window is already up on the screen in this example): $ControlCoordinates = ControlGetPos("Diagnostic Report", "", "[NAME:m_Details]") MsgBox(0, "Output from my AutoIt Test Script", "Autoit code believes the control to be at this location: " & @CRLF & $ControlCoordinates[0] & "," & $ControlCoordinates[1]) (Note: I have tried putting Opt("MouseCoordMode", 2) at the top of the code and it does not change the value, regardless of whether I do 0, 1, or 2 for the mode.) As you can see from the screen shot, AutoIt is getting "140" for the Y position. But the same control, when use AU3INFO.EXE to obtain its location, reports 164 for the Y position. I'm sure we're talking about the same control here. When I hover over the control with AU3INFO.EXE it reports the name "[NAME:m_Details]" for that control, and that is what I put into the code. There are no other controls on the window with that identifier, it is unique to that control in the example I have shown. The reason this is a problem is that I need to send a MouseClick to that place on the screen (ControlClick doesn't work for this program, I don't know why) and with MouseClick it's imperative that I get the position correct. It's not coming out correct this way and the mouse is clicking 24 pixels too high to register. What's wrong with the ControlGetPos function, and more importantly, why does AU3INFO.EXE get it right when it was written by the same people? What is AU3INFO doing right that AutoIt's ControlGetPos function is not doing right? How can I fix this so my code works correctly in all cases?
-
Okay, I found a solution. The secret is that, a 32-bit executable running on a 64 bit system, can access the files in the 64-bit System32 folder via a special secret folder named "Sysnative". Here's my code again, modified, this time it works in AutoIt on 32 and 64. If @OSArch == "X64" Then $WindowsActualTrueSystemFolder = @WindowsDir & "sysnative" Else $WindowsActualTrueSystemFolder = @SystemDir EndIf $OutputHandle = Run($WindowsActualTrueSystemFolder & "" & "netsh.exe mbn show readyinfo int=*", "", @SW_HIDE, $STDOUT_CHILD) While 1 $RunResults = $RunResults & StdoutRead($OutputHandle) If @error Then ExitLoop WEnd MsgBox (0, "Output", $RunResults)
-
I'm trying to write a script that gets back the results of the RUN command running NETSH, and then parses the results. The command works on 32-bit win7, and I can parse the results, but, for some reason it doesn't work right when I run it on a 64-bit win7 system. It appears as though the 64-bit version of NETSH on win7 has different capabilities than the 32-bit version (both exist on the win7 system I'm running), and one will return me the results I want while the other one tells me an error that the command is not available. Funny thing is, I'm having trouble figuring out which one is which, and anyway, how to get the one that I want, to run. Here's the code: $OutputHandle = Run("netsh.exe mbn show readyinfo int=*", "", @SW_HIDE, $STDOUT_CHILD) While 1 $RunResults = $RunResults & StdoutRead($OutputHandle) If @error Then ExitLoop WEnd MsgBox (0, "Output", $RunResults) Note: The code uses "MBN" which is a windows-7-and-later command only. It is looking for a Windows-Mobile-Broadband-enabled WWAN adapter, in my case, an AT&T card. If you have a similar adapter, it should return a set of statistics about the adapter, or, the words "The given interface is not present or not a Mobile Broadband interface" if you don't have one. On a 32-bit system that works fine. I get the text back that I was expecting. On a 64-bit system (running the 32-bit version of AutoIt), I get "The following command was not found: mbn show readyinfo int=*" If I open up a command prompt on that computer, and type the command, it works fine and I get the text I expect. If I open up a command prompt on that computer, and type the command but point it to the \Windows\SysWOW64\netsh.exe instead, I get the error "the following command was not found..." just like Autoit gets. So clearly this is a 32/64 problem. But it's critical to me that I distribute a single 32-bit EXE for this program, not have to do 32 and 64 separate versions (there are other problems that prevent me from compiling a 64-bit version in other parts of the program). So it appears as though AutoIt is doing the equivalent of running \Windows\SysWOW64\netsh.exe instead of the expected \Windows\System32\netsh.exe. Okay, so I have tried the following: - Running it shelled within @comspec /c ... Same undesired results, fails on 64 bit system. - Running it from @SystemDir\Netsh.exe ... Same undesired results, fails on 64 bit system. - Specifying \Windows\System32\Netsh.exe specifically ... Same undesired results, fails on 64 bit system. - Just for the heck of it, calling \Windows\SysWOW64\netsh.exe directly ... Same undesired results, fails on 64 bit system. - Running "netsh.exe ?" from the Autoit run command... it confirms my suspicion because the returned text does not contain the MBN command. - If I run "\Windows\SysWOW64\netsh.exe ?" at a command prompt ... it confirms my suspicion because the returned text does not contain the MBN command. The mapping between System32 and SysWOW64 confuzzles me anyway, and now I'm not even sure which of the two is the one that works, and which is the one that doesn't. Does anyone know how I can accomplish what I'm trying to do, but meet the following criteria? - Must be compiled as a 32-bit Autoit executable only. - Must run equally well on a 32-bit and 64-bit system. - Must be able to get actual valid results of "netsh.exe mbn show readyinfo int=*" on both 32- and 64-bit systems when run. - Must not ever return the bad error "The following command was not found" as a result of the command. (Returning "The given interface is not present" is a good result, meaning it's working) Anyone? Please help!
-
Okay, you know what? Maybe I don't need to get that detailed. Maybe what I'll try is this: - Focus the control. - ControlGetText to scrape the currently-selected item in the control. - Perform my string comparisons on the contents of that item. - If the string comparisons are "good" then press ENTER on the box (i.e, the right selection has been made and we can just confirm the box and be done). - If the string comparisons are "bad", press DOWN ARROW to get the next item to appear in the list, and then try another scrape and another comparison. - If the string comparisons never work after a few selections, press ENTER anyway just to get past the box with whatever is selected. That should get the same results, without me having to know how to scrape that box in detail.
-
I'm trying to use AutoIt to scrape the contents of a particular drop-down list in a particular dialog box. Can someone help me get the right code to do this? In this case, the application is Verizon VZAccess Manager, which is a connection manager program that controls the connection to Verizon for USB WWAN dongles. Sometimes, if you remove a WWAN card, if you plug in a different model of WWAN card, or if you plug in more than one WWAN card at the same time, then VZAM will put up a dialog box asking you which device you want to control. The list of possible devices is shown in a drop-down list in the dialog box. My AutoIt script needs to intelligently answer this dialog box and make the correct selection, based on some other information that I've already retrieved elsewhere. Ideally, I want to be able to scrape the contents of each item in that drop down list, and then be able to analyze and do string comparison operations on every single item in the drop down list (i.e., not just the selected item, but all of them, sequentially in turn), and then, based on the results of those string comparisons, have my AutoIt script make an intelligent choice as to which item should be selected, then select that item and press Enter. My problem is that every time I try to do ControlGetText on this box, the text that comes back is only the selected item, not the entire contents of the list. I'm trying to figure out the right set of functions to scrape this control in a useful way. I can WinGetText on the box, but it also only shows the currently selected list entry (i.e., it also can't see the other items in the drop down list), and, it mixes up that text with all the other text in the Window anyway, thus making WinGetText kind of useless for what I want to do. Attached to this post are a pair of screen shots of the dialog box showing that the "Text" is blank when looking at the control details, but, the text is visible in the "Visible Text" tab. Hopefully you can see my dilemma by looking at these screen shots. Here is my current code: $con_mgr="VZAccess Manager" $handle=WinGetHandle($con_mgr, "") If ($handle <> "") then $SubWindow = "Configured Device Removed" $handle=WinGetHandle($SubWindow, "") If ($handle <> "") then WinActivate($SubWindow) $VZAMListBoxString = ControlGetText($handle, "", "[CLASS:ComboBox; INSTANCE:1]") UpdateLogFile ("Retrieve VZAM List Box String: " & $VZAMListBoxString) EndIf EndIf The code above, only shows the currently selected text in that drop down list. How do I retrieve each of the items in that list, preferably into an array I can iterate through?
-
I've written some code that detects the presence of an Arduino-based device plugged into the USB port of a system, and records which COM port number its serial port is running on. In order to do this, I'm performing a WMI query. This WMI query executes quickly on some systems and slowly on other systems. (The systems where it executes slowly are old hardware test computers that have had a lot different kinds of USB cards plugged into them in the past, thus forcing WMI to enumerate through a fairly large database.) On the systems where the WMI query executes slowly, the GUI freezes, and I can't even move the main GUI window's position on the screen, until after the query is done. I want to figure out how to make my program's GUI be responsive to user input during this WMI query. Note: I know how to use the "Return Immediately" flag. However, even when I use the flag, then next line ("IsObj" in this case) will still have to wait until the query is done, so that line is the one where the freeze happens. Here is a sample snippet of my code. The lines where it freezes are the "ExecQuery" line (if I don't use the 0x10 flag), or the "IsObj" line (if I do use the 0x10 flag). ; Create the WMI object. This works instantly. $objWMI = ObjGet("winmgmts:\\.\root\cimv2") If IsObj($objWMI) then ; Everything is fine, we got a WMI Object Else ; Everything is not fine. We did not get a WMI object. Make obtrusive error message and bail out of the program. UpdateLogFile ("Internal program error. Unable to get handle to WMI object.") Exit() EndIf ; Execute the actual WMI query, specifically looking for the string "Arduino" in the COM port names. $objItems = $objWMI.ExecQuery("SELECT * from WIN32_SerialPort WHERE Caption LIKE '%Arduino%'","WQL",0x10+0x20) ; Notes on WMI Query: ; Common parameters (last parameter at the end there) are, for example: ; 0x10+0x20 ; 0x20 = wbemFlagForwardOnly ; meaning that it saves some memory, at the cost of certain ; functions (such as object.count) being unable to run. ; 0x10 = wbemFlagReturnImmediately ; Allows the WMI query to return immediately. This doesn't ; actually help me though! The next thing I do is perform ; an IsObj function... which will freeze my program until such ; time as the query is done. So it doesn't matter if I perform ; the WMI query with the "ReturnImmediately" flag... I'm just ; shifting the freeze from the line above, to the line below. ; either way, on a system with a bunch of WMI objects installed, ; such as a test system that's had a billion cards plugged into ; it before, then the query takes a long time (5 seconds or more) ; during which my program appears to freeze up. I have no idea how ; to get around this freeze... Either "IsObj" locks up my program ; until it finishes, or "ExecQuery" locks up my program until it ; finishes. How do I make my UI responsive during this query? If IsObj($objItems) Then ; If I have set the wbemFlagReturnImmediately flag, then the line above is the one that freezes the system. ; If I do not set the wbemFlagReturnImmediately flag, then the query above it is the one that freezes the system. ; I have confirmed this with debug prints. ; Ideally we would only get one result. But if we got more than one, loop through them all. For $objItem In $objItems $TempString = $objItem.DeviceID ; Whatever the LAST one was that we found, that's what we're going to assume is the Arduino. $ArduinoComPort = Int(StringReplace($TempString,"COM","",0,2)) UpdateLogFile("Found Arduino at COM" & $ArduinoComPort & ".") Next EndIf
-
I've googled and forum-searched a bit for this, and I can't seem to find exactly the right answer. Can anyone help? My AutoIt script does, among other things, some launching of some third-party programs that perform specialized tasks that I can't do from within AutoIt. Those programs require administrator privileges in order to get their work done. If those programs don't have administrator privileges when I shell out to them, then they will silently fail to accomplish their tasks. I want my AutoIt script (well, actually the EXE that I'm eventually going to compile and distribute from it) to require administrator privileges of its own before it will allow the user to continue. Please don't reply with instructions on how to make a shortcut to my AutoIt program, and then tick the "Administrator" tickybox in the shortcut, or describe how I can right-click on my AutoIt program and say "Run as administrator". I know how to do those things! In fact, that's how I could check to be sure that setting the AutoIt script to Admin privileges would work for my purposes. No, when I googled and forum-searched for this, that was what all the search results said: "Make a shortcut"... or "use the command-line RunAs..." etc... That's not what I'm asking here. I'm asking, how, within the AutoIt script code itself, how can I force it so that when a user runs my AutoIt program without admin privileges, that it will force the OS to put up the UAC box and ask the user if it's OK to allow my program to make changes to the system? Alternatively, if that can't be done, how can I, within AutoIt, check to see whether my program is currently running under administrator privileges, thus allowing me to put up my own error box and terminate my program? There was one search result that looked promising. The result talked about adding this line to my code: #AutoIt3Wrapper_Res_requestedExecutionLevel=requireAdministrator But when I put that line at the top of my code, there doesn't appear to be any change in the way the program runs. What is that line from, how is it supposed to work, and what am I doing wrong about implementing it? Are there any other ways to accomplish what I want?
-
What does the ampersand mean in a Send command?
tfabris replied to tfabris's topic in AutoIt General Help and Support
Thanks, guys! Removing the ampersands now and hoping the script Just Works. -
I had an old AutoIt script that I'm working on repurposing now for a new script. Back in the old days, it would send certain keystrokes to a commercial application. Here is a snippet: Send("{ALTDOWN}") Send("&t") Send("&d") Send("&m") Send("{ALTUP}") Sleep(500) Here's another snippet: Send("{CTRLDOWN}") Send("&k") Send("{CTRLUP}") Sleep(500) Clearly, the former is opening up the main menu with the ALT key and pressing ALT-t, d, m to select something three levels deep. The latter is trying to press the Ctrl+K hotkey in the application. But when I looked at the online help for the "SEND" command, I don't see what the ampersand means. The help for "SEND" only shows the ampersand in relation to its main usage as a string concatenator. It doesn't say how the ampersand character is related to the letters I send in the Send command. At least, it doesn't say that as far as I can tell. I'm sure I put them in there for a reason at some point in the past, but now I don't remember what the reason was. Now, if I remove the ampersands, the script seems to work as I expect it to work, as if the ampersands have no meaning. Was this a feature in an older release of AutoIt that isn't there any more? What was I doing?
-
Thanks for that explanation, Water! I have crafted a solution based on your explanation, thank you! I discovered that I could process GUI events in the middle of other functions just fine, so the explanation didn't make sense to me at first. I had to poke at things a bit to figure out exactly what it meant. I think a more accurate description, better than what is says in the Help, would be something like: "If the GUI fires off one of its event handlers for one of its controls, it won't process any more GUI events until that particular event handler returns." In other words, the problem isn't just that you can't call out to any functions at all, which is what I initially interpreted the explanation to mean. No, the problem is that you can't do a bunch of code (or sub-call out to a bunch of code) directly from the GUI event handler. If you do, then it won't ever return and the GUI never processes any other events. (I guess the GUI is single threaded or something?) Anyway, with that knowledge, I was able to come up with a perfect solution that doesn't require rewriting the whole thing in Message-Loop mode. Instead of trying to call my main processing function from the button code, the button code sets a flag. That flag is then read by the main program loop and then fired off from within the main program loop. *THAT* works fine and I can terminate the program easily wherever I want now, even if the processing loop takes hours. Pseudo code of my solution looks something like this: ; ------------- ; BAD (ORIGINAL) CODE ; ------------- GUICreate("Test Application") GUICtrlSetOnEvent($GoButton, "ProcessingLoop") While 1 Sleep(1000) Wend Func ProcessingLoop() ;Do lotsa stuff End Func ; ------------- ; GOOD (MY SOLUTION) CODE ; ------------- Global $GoFlag = 0 GUICreate("Test Application") GUICtrlSetOnEvent($GoButton, "SetGoFlag") While 1 Sleep(1000) If $GoFlag == 1 Then ProcessingLoop() $GoFlag = 0 EndIf Wend Func SetGoFlag() $GoFlag = 1 End Func Func ProcessingLoop() ;Do lotsa stuff End Func
-
Can anyone tell me what I'm doing wrong here? Run this program and notice that, you can close the application just fine if you close it before pressing the "Being Processing Now" button. Then run it again, and notice that, you cannot close the application after pressing the "Begin Processing Now" button. Is there a way to fix this? ; Example of problem I'm having with the GUI not closing. ; How do I fix this? #include <GuiEdit.au3> #include <ButtonConstants.au3> #include <EditConstants.au3> #include <GUIConstantsEx.au3> #include <StaticConstants.au3> #include <WindowsConstants.au3> Opt("GUIOnEventMode", 1) $MainForm = GUICreate("Test Application", 600, 400, 200, 200, BitOR($WS_MAXIMIZEBOX,$WS_MINIMIZEBOX,$WS_SIZEBOX,$WS_THICKFRAME,$WS_SYSMENU,$WS_CAPTION,$WS_OVERLAPPEDWINDOW,$WS_TILEDWINDOW,$WS_POPUP,$WS_POPUPWINDOW,$WS_GROUP,$WS_TABSTOP,$WS_BORDER,$WS_CLIPSIBLINGS)) GUISetOnEvent($GUI_EVENT_CLOSE, "MainFormClose") $LogOutputTextBox = GUICtrlCreateEdit("", 8, 8, 580, 280, BitOR($ES_READONLY,$ES_WANTRETURN,$WS_HSCROLL,$WS_VSCROLL)) $GoButton = GUICtrlCreateButton("Begin Processing Now !", 8, 300, 237, 33, $WS_GROUP) GUICtrlSetOnEvent($GoButton, "ProcessingLoop") GUISetState(@SW_SHOW) While 1 ; Loop where the main application waits for user input. ; This works... If it reaches this and the user presses the main ; form close button, then the application closes just fine. Sleep (1000) WEnd Func MainFormClose () ; This works fine, unless I'm in the processing loop. ; Why does this not work when I'm in the processing loop? MsgBox (0, "Closing", "You pressed the close button! Yay! Now exiting.") Exit EndFunc Func ProcessingLoop () ; This loop simulates the main application processing loop. ; This is the part that I cannot exit. I'm putting sleeps in ; here like crazy. Why doesn't the Close Button event fire ; when I'm in this loop? For $x = 1 to 30 ; If this were a real application, I would be doing something important here, ; like calculating the Question to the Ultimate Answer. But just for demo ; purposes, I'm going to just output some text. OutputText ("I am doing something. I have done something " & $x & " times now.") OutputText ("Boy I sure wish I could exit this application now.") OutputText ("Unfortunately, I must be task-killed now. WHY?!") Sleep (1000) Next EndFunc Func OutputText ($TextLine) ; Subroutine that makes it easy to output text to the edit control, for demonstration purposes. GuiCtrlSetData( $LogOutputTextBox, GuiCtrlRead ($LogOutputTextBox) & $TextLine & @CRLF) _GUICtrlEdit_LineScroll($LogOutputTextBox, 0, _GUICtrlEdit_GetLineCount($LogOutputTextBox)) EndFunc
-
Okay, that seems to have done it, but, there is one slight modification to the instructions: Selecting "Tools/Compile" gives me no checkboxes to unselect. I have to run the separate compile application and make sure x64 is unselected. But after that, yes, it seems to behave as you say. Problem solved! Thank you!
-
Updated information: When I reported the issue, I was running my script from within the AutoIt Script Editor with the F5 key. When I said that I tried compiling it, I was compiling the script from within the AutoIt script editor using the Tools/Compile function. I got the errors in those cases. I just discoverd that, If I use the external "compile script to EXE" utility, and, if I deliberately use the X86 version, and deliberately not check the "64 bit" checkbox, then it creates a Win32 executable that runs correctly. HOWEVER: This means that I cannot interactively develop and debug my script from within the script editor. (i.e., I have to compile it every time, run the compiled version, find its errors, then go back to the script editor). So does anyone know if there is a way I can make this run from withing the AutoIt Script Editor so that I can develop and debug more easily?
-
I'm trying to write an AutoIt script that detects when an Arduino device is plugged into the computer (and later, once I get the detection working, I will be sending Serial Port commands to it). I need the code to run identically on XP, Vista, and Win7, on both 32-bit and 64-bit flavors. I need the code to run natively, i.e., I can't resort to "compatibility mode". Here is my code: ; Set up custom defined error handler for COM objects, incase we get a COM error. $oMyError = ObjEvent("AutoIt.Error","MyErrFunc") ; Initialize a COM error handler $objWMI = ObjGet("winmgmts:\\.\root\cimv2") If IsObj($objWMI) then ; Everything is fine. Else ; Everything is not fine. Make an error message. MsgBox(0, "Error", "Internal program error. Unable to get handle to WMI object.") Exit EndIf $objItems = $objWMI.ExecQuery("SELECT * from WIN32_SerialPort WHERE Caption LIKE '%Arduino%'","WQL",0x10+0x20) If IsObj($objItems) Then For $objItem In $objItems MsgBox(0, "Located Arudino", "Found Arduino at: " & $objItem.DeviceID ) Next Else MsgBox(0, "Did not locate Arudino", "Did not locate Arduino") EndIf ; ------------------------------------------------------- ; CUSTOM DEFINED ERROR HANDLER FOR COM OBJECTS ; ------------------------------------------------------- Func MyErrFunc() Msgbox(0,"AutoItCOM Test","We intercepted a COM Error !" & @CRLF & @CRLF & _ "err.description is: " & @TAB & $oMyError.description & @CRLF & _ "err.windescription:" & @TAB & $oMyError.windescription & @CRLF & _ "err.number is: " & @TAB & hex($oMyError.number,8) & @CRLF & _ "err.lastdllerror is: " & @TAB & $oMyError.lastdllerror & @CRLF & _ "err.scriptline is: " & @TAB & $oMyError.scriptline & @CRLF & _ "err.source is: " & @TAB & $oMyError.source & @CRLF & _ "err.helpfile is: " & @TAB & $oMyError.helpfile & @CRLF & _ "err.helpcontext is: " & @TAB & $oMyError.helpcontext _ ) Endfunc The code runs fine on a 32-bit Windows7 computer. When I try to run it on a 64-bit Windows7 computer, here are the behaviors: - Sometimes I might get "The requested action with this object has failed." without the code even hitting my error handler. - Sometimes I might hit the error handler, which returns a "Generic Error" of 80020009. I tried the following things: - If I compile the script into an EXE, the EXE gets either one of those two same errors. - If I make a shortcut to that EXE, and set the shortcut properties to run in Compatibility Mode for Windows XP, then it works fine. I am concerned about: - The fact that it says "Win32" in the SELECT statement. I am worried that maybe that's the wrong SELECT statement for 64 bit systems? I don't know. - That SELECT statement works fine on a 64 bit system if I put it into a WMIC command line batch file. So maybe that statement is actually fine, and the "Win32" is actually just fine? - Googling is not helping, I can't seem to find out how to properly word that SELECT statement for a 64-bit system. So maybe that's a red herring. Can anyone else please reproduce this problem, using the above example code? (Remember: must be on 64-bit system to repro) Can anyone please help me find the right way to write this code so that it runs natively on Win7-64?