Leaderboard
Popular Content
Showing content with the highest reputation on 09/30/2021 in all areas
-
I made a TCP networking UDF https://github.com/OfficialLambdax/_netcode_Core-UDF I launched this Thread to go into details of certain features and how i plan to implement them, mostly TLS, the Optional User Database and 2FA. Im going to create seperate posts in this Thread whenever i have something to show off. Just to be clear, it is best to not use the UDF in your projects yet. Everything is subject to change and big potions of it need entire rewrites. So documentation and examples are ment to be created right before the UDF hits Alpha, thats not going to happen so fast. The entire encryption part would never been possible without TheXman's CryptoNG UDF https://www.autoitscript.com/forum/topic/201002-cryptong-udf-cryptography-api-next-gen/#comments So big thanks to him and his help!2 points
-
To make it easier to maintain the UIA code, I've decided to split the code this way: This new thread is used for the actual UIA UDFs. Ie. the files stored in Includes folders and named UIA_*.au3 or UIAEH_*.au3. The UIASpy thread contains only code that is used directly in the UIASpy GUI, but not the UIA UDFs in this new thread. Using UIA Code contains only example code, but neither UIA UDFs nor UIASpy. UIA Events contains GUI code to detect events and it contains example code, but neither UIA UDFs nor UIASpy. This means that every time the code in the UDF files in this new thread is updated (eg. because of Windows 10 feature updates twice a year), you must install the files in the Includes folders in the other threads yourself. The easiest way is simply to copy all UDF files to the Includes folders. UDF Files CUIAutomation2.au3 - UIA constants for Windows 7 used in the first examples CUIAutomation2-a.au3 - The original UIA constants for Windows 7 from junkew's thread UIA_AccVars.au3 - Used to calculate properties of type VT_UNKNOWN, copied and modified from this thread UIA_Constants.au3 - UIA constants (copied from UIA header files) up to and including Windows 10 1809 UIA_ConstNames.au3 - Contains functions for converting UIA constants from values to names UIA_Functions.au3 - A collection of small utility functions UIA_Functions-a.au3 - First version of utility functions UIA_ObjectFromTag.au3 - Creates callback objects used in event handlers, copied and modified from this post by trancexx UIA_SafeArray.au3 - Constants and functions to handle safearrays, copied from this thread UIA_Variant.au3 - Constants and functions to handle variants, copied from this thread UIAEH_AutomationEventHandler.au3 - Implements the AutomationEventHandler UIAEH_FocusChangedEventHandler.au3 - Implements the FocusChangedEventHandler UIAEH_NotificationEventHandler.au3 - Implements the NotificationEventHandler, published in Windows 10 1709 UIAEH_PropertyChangedEventHandler.au3 - Implements the PropertyChangedEventHandler UIAEH_StructureChangedEventHandler.au3 - Implements the StructureChangedEventHandler Folders The UI Automation projects can be stored in a folder structure this way: UI Automation\ Code\ - Using UIA code Events\ - UIA events Spy tool\ - UIASpy.au3 UDFs\ - UDF files The UDF files must be installed in Includes\ in the first three folders. Threads UIASpy - UI Automation Spy Tool is a GUI tool that provides information about windows and controls and their interconnection and provides functionality to generate sample code. UIASpy is essential for creating UI Automation code. In Using UI Automation Code in AutoIt you can find and download examples and read information about using UIA code. UI Automation Events is about implementing event handlers and includes GUIs to detect events. IUIAutomation MS framework automate chrome, FF, IE, .... created by junkew August 2013 is the first AutoIt thread on UIA code. Zip-file The zip contains source code for the UDF files. You need AutoIt 3.3.12 or later. Tested on Windows XP, Windows 7 and Windows 10. Comments are welcome. Let me know if there are any issues. UIAIncludes.7z1 point
-
MSSQL database backup via autoit
Earthshine reacted to t0nZ for a topic
HI @Aibek and welcome. I am just curious... $sqlcod1 = "EXEC [dbo].[ReleaseBackup]" Maybe ReleaseBackup is a "stored procedure" not existant in your "big database" ? Btw and maybe off topic.. usually for backup (and restore) I use a single line like that: RunWait(@ComSpec & " /c sqlcmd -U user -P password -S yourDBServer -Q ""backup database " & $DBname & " to disk = '" & $path2db & "backup\" & $DBname & ".dat' "" -o " & $path2db & "backup\log_backup.txt") Maybe you can try this way. Sure you can use variables also for user/psw/server. You will need the SQLCMD utility, if you run the script on the DB server often you already have it in path, otherwise check here1 point -
Automating Notepad This example is a response to a request by mLipok for a simple Notepad automation. Task: Create a simple script to fill up "Edit1" with HelloWorld, click "Save As...", enter filename and finally save it to disc. This involves automating Notepad or more generally an Edit control, it involves automating a menu and a Save As dialog. Note that "Edit1" (from AutoIt Window Info tool) is not a valid control identification in UI Automation code. Do not open Notepad in advance. This will be done in the code. Start the code by opening Notepad and create the UI Automation object through IUIAutomation interface. I almost always create the Desktop element. Note how you first get a pointer to the element (GetRootElement method of $oUIAutomation object), and then creates the object that represents the element through IUIAutomationElement interface. UI Automation elements are nearly always created this way through a pointer. #include "..\..\Includes\CUIAutomation2.au3" Example() Func Example() ; Open Notepad Run( "Notepad" ) Sleep( 1000 ) ; Create UI Automation object Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation ) If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "$oUIAutomation ERR" & @CRLF ) ConsoleWrite( "$oUIAutomation OK" & @CRLF ) ; Get Desktop element Local $pDesktop, $oDesktop $oUIAutomation.GetRootElement( $pDesktop ) $oDesktop = ObjCreateInterface( $pDesktop, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oDesktop ) Then Return ConsoleWrite( "$oDesktop ERR" & @CRLF ) ConsoleWrite( "$oDesktop OK" & @CRLF ) EndFunc Open Examples\Notepad\Notepad.au3 (empty) in SciTE. Add the code, run the code with F5 and leave Notepad open. Check that SciTE output is OK. Next step is to get the Notepad window as an UI Automation element. Open UIASpy (included in zip-file, keep UIASpy open throughout the entire example), place mouse cursor over Notepad title bar and press F2: (You can delete other windows in UIASpy by right-clicking treeview top windows (level one items).) $UIA_ClassNamePropertyId = "Notepad" is used to create a property condition to identify Notepad. Note that you can copy this line in UIASpy listview: Select the line in the listview, click "Right pane" item in main menu, click "Copy all or selected items to clipboard", paste the line into your code editor. Add this code to the existing code: ; --- Notepad window --- ConsoleWrite( "--- Notepad window ---" & @CRLF ) Local $pCondition ; Note that $UIA_ClassNamePropertyId maybe ia a CASE SENSITIVE condition $oUIAutomation.CreatePropertyCondition( $UIA_ClassNamePropertyId, "Notepad", $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) Local $pNotepad, $oNotepad $oDesktop.FindFirst( $TreeScope_Descendants, $pCondition, $pNotepad ) $oNotepad = ObjCreateInterface( $pNotepad, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oNotepad ) Then Return ConsoleWrite( "$oNotepad ERR" & @CRLF ) ConsoleWrite( "$oNotepad OK" & @CRLF ) EndFunc Note again how we first get a pointer to Notepad (FindFirst method of $oDesktop object, $oDesktop because the Desktop is the parent element of Notepad) and then creates the object. Also note that $oDesktop and $oNotepad are created in exactly the same way. Close the previous Notepad, run the code and leave Notepad open. Check that SciTE output is OK. Now, the actual automation starts: Fill up "Edit1" with HelloWorld. An automation task is almost always done in two or three steps: 1. Create condition to find element 2. Find the UI Automation element 3. Extract info or perform action Each of these steps can usually be done in 1 - 3 lines of UI Automation code. All three steps can usually be done in less that 10 lines of UI Automation code (common AutoIt debug/info code not included). To get the Notepad window above we only used two steps. The first automation task is to perform an action to fill out the Edit control with "HelloWorld". Place mouse cursor in the Edit control and press F1: (If there are two or more Notepad windows in UIASpy, you can delete the old windows (red) by right-clicking the treeview.) This time we can use $UIA_AutomationIdPropertyId = "15" to create a property condition to identify the Edit control. Add this code: ; --- Fill Edit element --- ConsoleWrite( "--- Fill Edit element ---" & @CRLF ) ; Note that $UIA_AutomationIdPropertyId is a STRING and maybe a CASE SENSITIVE condition $oUIAutomation.CreatePropertyCondition( $UIA_AutomationIdPropertyId, "15", $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) Local $pEdit, $oEdit $oNotepad.FindFirst( $TreeScope_Descendants, $pCondition, $pEdit ) $oEdit = ObjCreateInterface( $pEdit, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oEdit ) Then Return ConsoleWrite( "$oEdit ERR" & @CRLF ) ConsoleWrite( "$oEdit OK" & @CRLF ) EndFunc $oNotepad.FindFirst means that the search for the Edit control starts in the Notepad window. $oEdit reprecents the Edit control. Close the previous Notepad, run the code and leave Notepad open. Check that SciTE output is OK. The Edit control must be filled with "HelloWorld". This is an action that has to be performed on the Edit control. The following actions are available: (Scroll down UIASpy listview to see Control Patterns (actions).) The interesting action or pattern here is the ValuePattern. The action is created and performed this way: Local $pValue, $oValue $oEdit.GetCurrentPattern( $UIA_ValuePatternId, $pValue ) $oValue = ObjCreateInterface( $pValue, $sIID_IUIAutomationValuePattern, $dtagIUIAutomationValuePattern ) If Not IsObj( $oValue ) Then Return ConsoleWrite( "$oValue ERR" & @CRLF ) ConsoleWrite( "$oValue OK" & @CRLF ) $oValue.SetValue( "HelloWorld" ) EndFunc $oEdit.GetCurrentPattern means that a pattern is created that performs actions on the Edit control. GetCurrentPattern method returns a pointer where from the ValuePattern object ($oValue) can be created. $UIA_ValuePatternId and the ValuePattern interface is defined in CUIAutomation2.au3. The $oValue object represents the ValuePattern interface for the Edit control. $oValue.SetValue( "HelloWorld" ) sets the text in the Edit control. An action or pattern is almost always created and performed this way. Add the code, close the previous Notepad, run the code and leave Notepad open. Open File menu. Place mouse cursor over the File menu and press F1: (Scroll down UIASpy listview to see Control Patterns (actions) in bottom of image.) ; --- Open File menu --- ConsoleWrite( "--- Open File menu ---" & @CRLF ) Local $pCondition1 $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_MenuItemControlTypeId, $pCondition1 ) If Not $pCondition1 Then Return ConsoleWrite( "$pCondition1 ERR" & @CRLF ) ConsoleWrite( "$pCondition1 OK" & @CRLF ) Local $pCondition2 ; $UIA_NamePropertyId is LOCALIZED and maybe CASE SENSITIVE $oUIAutomation.CreatePropertyCondition( $UIA_NamePropertyId, "File", $pCondition2 ) ; File <<<<<<<<<<<<<<<<<<<< If Not $pCondition2 Then Return ConsoleWrite( "$pCondition2 ERR" & @CRLF ) ConsoleWrite( "$pCondition2 OK" & @CRLF ) ; And condition $oUIAutomation.CreateAndCondition( $pCondition1, $pCondition2, $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) Local $pFile, $oFile $oNotepad.FindFirst( $TreeScope_Descendants, $pCondition, $pFile ) $oFile = ObjCreateInterface( $pFile, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oFile ) Then Return ConsoleWrite( "$oFile ERR" & @CRLF ) ConsoleWrite( "$oFile OK" & @CRLF ) Local $pInvoke, $oInvoke $oFile.GetCurrentPattern( $UIA_InvokePatternId, $pInvoke ) $oInvoke = ObjCreateInterface( $pInvoke, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern ) If Not IsObj( $oInvoke ) Then Return ConsoleWrite( "$oInvoke ERR" & @CRLF ) ConsoleWrite( "$oInvoke OK" & @CRLF ) $oInvoke.Invoke() Sleep( 100 ) EndFunc The Invoke action or pattern is used to click and open the File menu. Note the similarity between the code for InvokePattern and ValuePattern above. When a menu, dialog box or child window is opened it need some time to open. You must add a Sleep statement. Add the code, change "File" to the corresponding word in your own language (copy the word from the listview), close the previous Notepad (don't save), run the code and leave Notepad open. Click "Save As..." menu. If the File menu that was opened above is closed, then open it manually with a mouse click. Place mouse cursor over the "Save As..." menu and press F1: ; --- Click "Save As..." menu --- ConsoleWrite( "--- Click ""Save As..."" menu ---" & @CRLF ) ; Reuse $pCondition1 above ; Note that $UIA_AutomationIdPropertyId is a STRING and maybe a CASE SENSITIVE condition $oUIAutomation.CreatePropertyCondition( $UIA_AutomationIdPropertyId, "4", $pCondition2 ) If Not $pCondition2 Then Return ConsoleWrite( "$pCondition2 ERR" & @CRLF ) ConsoleWrite( "$pCondition2 OK" & @CRLF ) ; And condition $oUIAutomation.CreateAndCondition( $pCondition1, $pCondition2, $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) Local $pSaveAs, $oSaveAs $oNotepad.FindFirst( $TreeScope_Descendants, $pCondition, $pSaveAs ) $oSaveAs = ObjCreateInterface( $pSaveAs, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oSaveAs ) Then Return ConsoleWrite( "$oSaveAs ERR" & @CRLF ) ConsoleWrite( "$oSaveAs OK" & @CRLF ) $oSaveAs.GetCurrentPattern( $UIA_InvokePatternId, $pInvoke ) $oInvoke = ObjCreateInterface( $pInvoke, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern ) If Not IsObj( $oInvoke ) Then Return ConsoleWrite( "$oInvoke ERR" & @CRLF ) ConsoleWrite( "$oInvoke OK" & @CRLF ) $oInvoke.Invoke() Sleep( 1000 ) EndFunc Note how similar the "Open File menu" code and the "Click Save As... menu" code is. Note also the long Sleep because it's a "Save As" dialog with a large number of elements. Add the code, close the previous Notepad (don't save), run the code and leave Notepad and Save As open. Save As window. Place mouse cursor over Save As title bar and press F2: ; --- Save As window --- ConsoleWrite( "--- Save As window ---" & @CRLF ) ; Note that $UIA_ClassNamePropertyId maybe ia a CASE SENSITIVE condition $oUIAutomation.CreatePropertyCondition( $UIA_ClassNamePropertyId, "#32770", $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) Local $pSaveAsWin, $oSaveAsWin $oNotepad.FindFirst( $TreeScope_Descendants, $pCondition, $pSaveAsWin ) $oSaveAsWin = ObjCreateInterface( $pSaveAsWin, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oSaveAsWin ) Then Return ConsoleWrite( "$oSaveAsWin ERR" & @CRLF ) ConsoleWrite( "$oSaveAsWin OK" & @CRLF ) EndFunc The rest of the automation tasks is about the Save As window. Therefore we want to use the Save As window as the starting point. Not Notepad. Add the code, close the previous Save As and Notepad (don't save), run the code and leave Notepad and Save As open. Set File name. Place mouse cursor over File name Edit control and press F1: ; --- Set File name --- ConsoleWrite( "--- Set File name ---" & @CRLF ) ; Note that $UIA_AutomationIdPropertyId is a STRING and maybe a CASE SENSITIVE condition $oUIAutomation.CreatePropertyCondition( $UIA_AutomationIdPropertyId, "1001", $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) $oSaveAsWin.FindFirst( $TreeScope_Descendants, $pCondition, $pEdit ) $oEdit = ObjCreateInterface( $pEdit, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oEdit ) Then Return ConsoleWrite( "$oEdit ERR" & @CRLF ) ConsoleWrite( "$oEdit OK" & @CRLF ) $oEdit.GetCurrentPattern( $UIA_ValuePatternId, $pValue ) $oValue = ObjCreateInterface( $pValue, $sIID_IUIAutomationValuePattern, $dtagIUIAutomationValuePattern ) If Not IsObj( $oValue ) Then Return ConsoleWrite( "$oValue ERR" & @CRLF ) ConsoleWrite( "$oValue OK" & @CRLF ) $oValue.SetValue( "HelloWorld.txt" ) EndFunc $oSaveAsWin.FindFirst searches in the Save As window. $oEdit is now the File name Edit control in the Save As window. The file name is set to "HelloWorld.txt". Add the code, close the previous Save As and Notepad (don't save), run the code and leave Notepad and Save As open. Click Save button. Place mouse cursor over Save button and press F1: ; --- Click Save button --- ConsoleWrite( "--- Click Save button ---" & @CRLF ) $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_ButtonControlTypeId, $pCondition1 ) If Not $pCondition1 Then Return ConsoleWrite( "$pCondition1 ERR" & @CRLF ) ConsoleWrite( "$pCondition1 OK" & @CRLF ) ; Note that $UIA_AutomationIdPropertyId is a STRING and maybe a CASE SENSITIVE condition $oUIAutomation.CreatePropertyCondition( $UIA_AutomationIdPropertyId, "1", $pCondition2 ) If Not $pCondition2 Then Return ConsoleWrite( "$pCondition2 ERR" & @CRLF ) ConsoleWrite( "$pCondition2 OK" & @CRLF ) ; And condition $oUIAutomation.CreateAndCondition( $pCondition1, $pCondition2, $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) Local $pSave, $oSave $oSaveAsWin.FindFirst( $TreeScope_Descendants, $pCondition, $pSave ) $oSave = ObjCreateInterface( $pSave, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oSave ) Then Return ConsoleWrite( "$oSave ERR" & @CRLF ) ConsoleWrite( "$oSave OK" & @CRLF ) $oSave.GetCurrentPattern( $UIA_InvokePatternId, $pInvoke ) $oInvoke = ObjCreateInterface( $pInvoke, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern ) If Not IsObj( $oInvoke ) Then Return ConsoleWrite( "$oInvoke ERR" & @CRLF ) ConsoleWrite( "$oInvoke OK" & @CRLF ) $oInvoke.Invoke() EndFunc Add the code, close the previous Save As and Notepad (don't save) and run the code. All code (Examples\Notepad\NotepadAll.au3): #include "..\..\Includes\CUIAutomation2.au3" Example() Func Example() ; Open Notepad Run( "Notepad" ) Sleep( 1000 ) ; Create UI Automation object Local $oUIAutomation = ObjCreateInterface( $sCLSID_CUIAutomation, $sIID_IUIAutomation, $dtagIUIAutomation ) If Not IsObj( $oUIAutomation ) Then Return ConsoleWrite( "$oUIAutomation ERR" & @CRLF ) ConsoleWrite( "$oUIAutomation OK" & @CRLF ) ; Get Desktop element Local $pDesktop, $oDesktop $oUIAutomation.GetRootElement( $pDesktop ) $oDesktop = ObjCreateInterface( $pDesktop, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oDesktop ) Then Return ConsoleWrite( "$oDesktop ERR" & @CRLF ) ConsoleWrite( "$oDesktop OK" & @CRLF ) ; --- Notepad window --- ConsoleWrite( "--- Notepad window ---" & @CRLF ) Local $pCondition ; Note that $UIA_ClassNamePropertyId maybe ia a CASE SENSITIVE condition $oUIAutomation.CreatePropertyCondition( $UIA_ClassNamePropertyId, "Notepad", $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) Local $pNotepad, $oNotepad $oDesktop.FindFirst( $TreeScope_Descendants, $pCondition, $pNotepad ) $oNotepad = ObjCreateInterface( $pNotepad, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oNotepad ) Then Return ConsoleWrite( "$oNotepad ERR" & @CRLF ) ConsoleWrite( "$oNotepad OK" & @CRLF ) ; --- Fill Edit element --- ConsoleWrite( "--- Fill Edit element ---" & @CRLF ) ; Note that $UIA_AutomationIdPropertyId is a STRING and maybe a CASE SENSITIVE condition $oUIAutomation.CreatePropertyCondition( $UIA_AutomationIdPropertyId, "15", $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) Local $pEdit, $oEdit $oNotepad.FindFirst( $TreeScope_Descendants, $pCondition, $pEdit ) $oEdit = ObjCreateInterface( $pEdit, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oEdit ) Then Return ConsoleWrite( "$oEdit ERR" & @CRLF ) ConsoleWrite( "$oEdit OK" & @CRLF ) Local $pValue, $oValue $oEdit.GetCurrentPattern( $UIA_ValuePatternId, $pValue ) $oValue = ObjCreateInterface( $pValue, $sIID_IUIAutomationValuePattern, $dtagIUIAutomationValuePattern ) If Not IsObj( $oValue ) Then Return ConsoleWrite( "$oValue ERR" & @CRLF ) ConsoleWrite( "$oValue OK" & @CRLF ) $oValue.SetValue( "HelloWorld" ) ; --- Open File menu --- ConsoleWrite( "--- Open File menu ---" & @CRLF ) Local $pCondition1 $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_MenuItemControlTypeId, $pCondition1 ) If Not $pCondition1 Then Return ConsoleWrite( "$pCondition1 ERR" & @CRLF ) ConsoleWrite( "$pCondition1 OK" & @CRLF ) Local $pCondition2 ; $UIA_NamePropertyId is LOCALIZED and maybe CASE SENSITIVE $oUIAutomation.CreatePropertyCondition( $UIA_NamePropertyId, "File", $pCondition2 ) ; File <<<<<<<<<<<<<<<<<<<< If Not $pCondition2 Then Return ConsoleWrite( "$pCondition2 ERR" & @CRLF ) ConsoleWrite( "$pCondition2 OK" & @CRLF ) ; And condition $oUIAutomation.CreateAndCondition( $pCondition1, $pCondition2, $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) Local $pFile, $oFile $oNotepad.FindFirst( $TreeScope_Descendants, $pCondition, $pFile ) $oFile = ObjCreateInterface( $pFile, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oFile ) Then Return ConsoleWrite( "$oFile ERR" & @CRLF ) ConsoleWrite( "$oFile OK" & @CRLF ) Local $pInvoke, $oInvoke $oFile.GetCurrentPattern( $UIA_InvokePatternId, $pInvoke ) $oInvoke = ObjCreateInterface( $pInvoke, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern ) If Not IsObj( $oInvoke ) Then Return ConsoleWrite( "$oInvoke ERR" & @CRLF ) ConsoleWrite( "$oInvoke OK" & @CRLF ) $oInvoke.Invoke() Sleep( 100 ) ; --- Click "Save As..." menu --- ConsoleWrite( "--- Click ""Save As..."" menu ---" & @CRLF ) ; Reuse $pCondition1 above ; Note that $UIA_AutomationIdPropertyId is a STRING and maybe a CASE SENSITIVE condition $oUIAutomation.CreatePropertyCondition( $UIA_AutomationIdPropertyId, "4", $pCondition2 ) If Not $pCondition2 Then Return ConsoleWrite( "$pCondition2 ERR" & @CRLF ) ConsoleWrite( "$pCondition2 OK" & @CRLF ) ; And condition $oUIAutomation.CreateAndCondition( $pCondition1, $pCondition2, $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) Local $pSaveAs, $oSaveAs $oNotepad.FindFirst( $TreeScope_Descendants, $pCondition, $pSaveAs ) $oSaveAs = ObjCreateInterface( $pSaveAs, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oSaveAs ) Then Return ConsoleWrite( "$oSaveAs ERR" & @CRLF ) ConsoleWrite( "$oSaveAs OK" & @CRLF ) $oSaveAs.GetCurrentPattern( $UIA_InvokePatternId, $pInvoke ) $oInvoke = ObjCreateInterface( $pInvoke, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern ) If Not IsObj( $oInvoke ) Then Return ConsoleWrite( "$oInvoke ERR" & @CRLF ) ConsoleWrite( "$oInvoke OK" & @CRLF ) $oInvoke.Invoke() Sleep( 1000 ) ; --- Save As window --- ConsoleWrite( "--- Save As window ---" & @CRLF ) ; Note that $UIA_ClassNamePropertyId maybe ia a CASE SENSITIVE condition $oUIAutomation.CreatePropertyCondition( $UIA_ClassNamePropertyId, "#32770", $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) Local $pSaveAsWin, $oSaveAsWin $oNotepad.FindFirst( $TreeScope_Descendants, $pCondition, $pSaveAsWin ) $oSaveAsWin = ObjCreateInterface( $pSaveAsWin, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oSaveAsWin ) Then Return ConsoleWrite( "$oSaveAsWin ERR" & @CRLF ) ConsoleWrite( "$oSaveAsWin OK" & @CRLF ) ; --- Set File name --- ConsoleWrite( "--- Set File name ---" & @CRLF ) ; Note that $UIA_AutomationIdPropertyId is a STRING and maybe a CASE SENSITIVE condition $oUIAutomation.CreatePropertyCondition( $UIA_AutomationIdPropertyId, "1001", $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) $oSaveAsWin.FindFirst( $TreeScope_Descendants, $pCondition, $pEdit ) $oEdit = ObjCreateInterface( $pEdit, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oEdit ) Then Return ConsoleWrite( "$oEdit ERR" & @CRLF ) ConsoleWrite( "$oEdit OK" & @CRLF ) $oEdit.GetCurrentPattern( $UIA_ValuePatternId, $pValue ) $oValue = ObjCreateInterface( $pValue, $sIID_IUIAutomationValuePattern, $dtagIUIAutomationValuePattern ) If Not IsObj( $oValue ) Then Return ConsoleWrite( "$oValue ERR" & @CRLF ) ConsoleWrite( "$oValue OK" & @CRLF ) $oValue.SetValue( "HelloWorld.txt" ) ; --- Click Save button --- ConsoleWrite( "--- Click Save button ---" & @CRLF ) $oUIAutomation.CreatePropertyCondition( $UIA_ControlTypePropertyId, $UIA_ButtonControlTypeId, $pCondition1 ) If Not $pCondition1 Then Return ConsoleWrite( "$pCondition1 ERR" & @CRLF ) ConsoleWrite( "$pCondition1 OK" & @CRLF ) ; Note that $UIA_AutomationIdPropertyId is a STRING and maybe a CASE SENSITIVE condition $oUIAutomation.CreatePropertyCondition( $UIA_AutomationIdPropertyId, "1", $pCondition2 ) If Not $pCondition2 Then Return ConsoleWrite( "$pCondition2 ERR" & @CRLF ) ConsoleWrite( "$pCondition2 OK" & @CRLF ) ; And condition $oUIAutomation.CreateAndCondition( $pCondition1, $pCondition2, $pCondition ) If Not $pCondition Then Return ConsoleWrite( "$pCondition ERR" & @CRLF ) ConsoleWrite( "$pCondition OK" & @CRLF ) Local $pSave, $oSave $oSaveAsWin.FindFirst( $TreeScope_Descendants, $pCondition, $pSave ) $oSave = ObjCreateInterface( $pSave, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) If Not IsObj( $oSave ) Then Return ConsoleWrite( "$oSave ERR" & @CRLF ) ConsoleWrite( "$oSave OK" & @CRLF ) $oSave.GetCurrentPattern( $UIA_InvokePatternId, $pInvoke ) $oInvoke = ObjCreateInterface( $pInvoke, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern ) If Not IsObj( $oInvoke ) Then Return ConsoleWrite( "$oInvoke ERR" & @CRLF ) ConsoleWrite( "$oInvoke OK" & @CRLF ) $oInvoke.Invoke() EndFunc SciTE output: $oUIAutomation OK $oDesktop OK --- Notepad window --- $pCondition OK $oNotepad OK --- Fill Edit element --- $pCondition OK $oEdit OK $oValue OK --- Open File menu --- $pCondition1 OK $pCondition2 OK $pCondition OK $oFile OK $oInvoke OK --- Click "Save As..." menu --- $pCondition2 OK $pCondition OK $oSaveAs OK $oInvoke OK --- Save As window --- $pCondition OK $oSaveAsWin OK --- Set File name --- $pCondition OK $oEdit OK $oValue OK --- Click Save button --- $pCondition1 OK $pCondition2 OK $pCondition OK $oSave OK $oInvoke OK Maybe somebody can show how to implement such a Notepad automation with the functions in UIAWrappers.au3 and with classic code. Summary The two most important objects in UI Automation code are the $oUIAutomation and $oUIElement objects created from IUIAutomation and IUIAutomationElement interfaces. An UI Automation element object that represents a window or control is always created with the IUIAutomationElement interface through a pointer to the element object: $oDesktop = ObjCreateInterface( $pDesktop, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) $oNotepad = ObjCreateInterface( $pNotepad, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) $oEdit = ObjCreateInterface( $pEdit, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) An UI Automation task is almost always done in two or three steps: 1. Create condition to find element 2. Find the UI Automation element 3. Extract info or perform action Each of these steps can usually be done in 1 - 3 lines of UI Automation code. All three steps can usually be done in less that 10 lines of UI Automation code (common AutoIt debug/info code not included). UI Automation actions (patterns) are performed through pattern interfaces, objects and methods. The code is nearly always implemented this way: Fill an Edit control: Local $pValue, $oValue $oEdit.GetCurrentPattern( $UIA_ValuePatternId, $pValue ) $oValue = ObjCreateInterface( $pValue, $sIID_IUIAutomationValuePattern, $dtagIUIAutomationValuePattern ) If Not IsObj( $oValue ) Then Return ConsoleWrite( "$oValue ERR" & @CRLF ) ConsoleWrite( "$oValue OK" & @CRLF ) $oValue.SetValue( "HelloWorld" ) $oEdit is an Edit control. The $oValue object represents the ValuePattern interface for the Edit control. $oValue.SetValue() sets the text in the Edit control. Click a menu item: Local $pInvoke, $oInvoke $oFile.GetCurrentPattern( $UIA_InvokePatternId, $pInvoke ) $oInvoke = ObjCreateInterface( $pInvoke, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern ) If Not IsObj( $oInvoke ) Then Return ConsoleWrite( "$oInvoke ERR" & @CRLF ) ConsoleWrite( "$oInvoke OK" & @CRLF ) $oInvoke.Invoke() Sleep( 100 ) $oFile is a File menu. The $oInvoke object represents the InvokePattern interface for the File menu. $oInvoke.Invoke() clicks the File menu. Sleep( 100 ) gives the File menu time to open. Click a button control: $oSave.GetCurrentPattern( $UIA_InvokePatternId, $pInvoke ) $oInvoke = ObjCreateInterface( $pInvoke, $sIID_IUIAutomationInvokePattern, $dtagIUIAutomationInvokePattern ) If Not IsObj( $oInvoke ) Then Return ConsoleWrite( "$oInvoke ERR" & @CRLF ) ConsoleWrite( "$oInvoke OK" & @CRLF ) $oInvoke.Invoke() $oSave is a Save button. The $oInvoke object represents the InvokePattern interface for the Save button. $oInvoke.Invoke() clicks the Save button. When writing UI Automation code, it's easiest to write the code in small steps and test the code after each step. Error management based on checking objects with IsObj() and ConsoleWrite() is required and sufficient. It's very rare necessary to use an actual object (COM) error handler. Too small Sleep times after a menu, dialog or window is opened is a common error.1 point
-
I certainly can. The subitems with the detail information are children of the row (parent). This function prints the name and value of all children to a parent: Func ListChildren( $oParent ) Local $pCondition $oUIAutomation.CreateTrueCondition( $pCondition ) If Not $pCondition Then Return Local $pUIElementArray, $oUIElementArray, $iElements $oParent.FindAll( $TreeScope_Children, $pCondition, $pUIElementArray ) $oUIElementArray = ObjCreateInterface( $pUIElementArray, $sIID_IUIAutomationElementArray, $dtagIUIAutomationElementArray ) $oUIElementArray.Length( $iElements ) If Not $iElements Then Return Local $pUIElement, $oUIElement, $name, $value For $i = 0 To $iElements - 1 $oUIElementArray.GetElement( $i, $pUIElement ) $oUIElement = ObjCreateInterface( $pUIElement, $sIID_IUIAutomationElement, $dtagIUIAutomationElement ) $oUIElement.GetCurrentPropertyValue( $UIA_NamePropertyId, $name ) $oUIElement.GetCurrentPropertyValue( $UIA_ValueValuePropertyId, $value ) If $name <> "" Then ConsoleWrite( " " & $name & ": " & $value & @CRLF ) Next EndFunc Note that I have copied most of the code. Call the function like this just before the Next statement ListChildren( $oUIElement ) Regards Lars.1 point