Leaderboard
Popular Content
Showing content with the highest reputation on 02/28/2023 in all areas
-
Regex validates as true when it should not
Musashi and 2 others reacted to pixelsearch for a topic
@Kovacic that's an interesting pattern you shared with us, because the match requires, at least : * A lower case letter * An upper case letter * A digit * A punctuation sign May I suggest, if Active Directory allows it, to use any punctuation sign found in the appropriate POSIX character class, for example : It would simplify the pattern and get rid of the punctuation string found actually in your pattern, which includes the escaped metacharacters, e.g. \ ^ - ] If I'm not mistaken, there are 32 punctuation characters in [:punct:] , all of them found in the interval chr(33) to chr(126) , e.g. 94 characters found from chr(33) to chr(126) -52 for the alphabetical characters (upper & lower) -10 for digits === 32 punctuation characters in [:punct:] @ioa747 : as you can see in the pic above, version 2.5k will have a different context menu compared to version 2.5j but it takes time to rearrange it exactly as I wish... A major improvement will be to save & restore binary data as UTF8 (necessary in some cases),3 points -
Overview The example is named AutoIt and Python Integration. Integration here means data integration, where data e.g. arrays are passed back and forth between AutoIt and Python scripts. The technique is based on ROT objects registered in the Running Object Table (ROT). Relevant threads IRunningObjectTable AutoIt and Perl Integration AutoIt and VBScript Integration (middle of post) Execute VBScript method in AutoIt First post Running Object Table (ROT) A summary of the technique Two AutoIt Scripts Which data types can be passed? AutoIt and Python Integration Python Installation AutoIt and Python Simple examples Prime Numbers Python calculation of prime numbers and passing data to AutoIt Also prime number calculation with AutoIt and VB.NET code Runtimes Speed comparison of AutoIt, Python and VB.NET code Based on the prime number calculations above Python and VBScript Pass array between Python and VBScript 7z-file Running Object Table (ROT) The Running Object Table (ROT) is a system global table where objects can register themselves. This makes the objects available in processes other than the process in which the objects are created. These processes can be implemented in different programming languages. A ROT object is typically used to exchange data between the processes. An object is registered in the ROT through the IRunningObjectTable interface. A script that registers an object in the ROT is referred to as a server. A ROT object is usually available in the table as long as the server is running. IRunningObjectTable.au3 must be included in the server script. A script that uses an object in the ROT is referred to as a client. A client connects to a ROT object through functions such as GetObject(), GetActiveObject(), and the like. Therefore, a client doesn't depend on IRunningObjectTable.au3. A client and a server can exchange data through the ROT object. But two clients can also exchange data through a common server. Since IRunningObjectTable.au3 is an AutoIt include file, it's easy to create the server as an AutoIt script. As the data transfer takes place using COM objects, only COM compatible data can be transferred. If sender and receiver scripts are coded in different languages, then data exchange also depends on the data types being represented in both languages. Most script languages support simple data types such as integers, floats and strings as well as advanced data types such as arrays and dictionary objects. An advantage of using ROT objects is that internal data types of e.g. array elements are preserved during a data transfer. Below is demonstrated data exchange between AutoIt and Python. Eg. how to pass an array from AutoIt to Python, perform calculations with functions in the NumPy package, and return the results to AutoIt. But first there is a test on passing data between two AutoIt scripts. Two AutoIt ScriptsWhich data types can be exchanged through a ROT object between two AutoIt scripts running in two different processes? Examples in Examples\AutoItAutoIt\ folder. These are slight variations of the VarGetType() example in the help file. Server.au3: #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y Opt( "MustDeclareVars", 1 ) #include <GUIConstantsEx.au3> #include "..\..\Includes\IRunningObjectTable.au3" Server() Func Server() ; Create a default ROT-object (Dictionary object) ; The script that creates the ROT object is the server ; The ROT object is available while the server is running Local $sDataTransferObject = "DataTransferObject", $oDict $oDict = ROT_CreateDefaultObject( $sDataTransferObject, 0 ) ; 0 -> Non-unique ; AutoIt data types Local $aArray[2] = [ 1, "Example" ] Local $mMap[] Local $dBinary = Binary( "0x00204060" ) Local $bBoolean = False Local $pPtr = Ptr( -1 ) Local $hWnd = WinGetHandle( AutoItWinGetTitle() ) Local $iInt = 1 Local $fFloat = 2.0 Local $oObject = ObjCreate( "Scripting.Dictionary" ) Local $sString = "Some text" Local $tStruct = DllStructCreate( "wchar[256]" ) Local $vKeyword = Default Local $fuFunc = ConsoleWrite Local $fuUserFunc = Test ; Add data to $oDict $oDict.Item( "$aArray" ) = $aArray $oDict.Item( "$mMap" ) = $mMap $oDict.Item( "$dBinary" ) = $dBinary $oDict.Item( "$bBoolean" ) = $bBoolean $oDict.Item( "$pPtr" ) = $pPtr $oDict.Item( "$hWnd" ) = $hWnd $oDict.Item( "$iInt" ) = $iInt $oDict.Item( "$fFloat" ) = $fFloat $oDict.Item( "$oObject" ) = $oObject $oDict.Item( "$sString" ) = $sString $oDict.Item( "$tStruct" ) = $tStruct $oDict.Item( "$vKeyword" ) = $vKeyword $oDict.Item( "$fuFunc" ) = $fuFunc $oDict.Item( "$fuUserFunc" ) = $fuUserFunc ; Create server GUI Local $hGui = GUICreate( "Server", 200, 70, 200, 50 ) ; Show GUI GUISetState() MsgBox( 0, "Variable Types on Server", _ "$aArray : " & @TAB & @TAB & VarGetType( $aArray ) & " variable type" & @CRLF & _ "$mMap : " & @TAB & @TAB & VarGetType( $mMap ) & " variable type" & @CRLF & _ "$dBinary : " & @TAB & VarGetType( $dBinary ) & " variable type" & @CRLF & _ "$bBoolean : " & @TAB & VarGetType( $bBoolean ) & " variable type" & @CRLF & _ "$pPtr : " & @TAB & @TAB & VarGetType( $pPtr ) & " variable type" & @CRLF & _ "$hWnd : " & @TAB & @TAB & VarGetType( $hWnd ) & " variable type" & @CRLF & _ "$iInt : " & @TAB & @TAB & VarGetType( $iInt ) & " variable type" & @CRLF & _ "$fFloat : " & @TAB & @TAB & VarGetType( $fFloat ) & " variable type" & @CRLF & _ "$oObject : " & @TAB & VarGetType( $oObject ) & " variable type" & @CRLF & _ "$sString : " & @TAB & VarGetType( $sString ) & " variable type" & @CRLF & _ "$tStruct : " & @TAB & VarGetType( $tStruct ) & " variable type" & @CRLF & _ "$vKeyword : " & @TAB & VarGetType( $vKeyword ) & " variable type" & @CRLF & _ "$fuFunc : " & @TAB & VarGetType( $fuFunc ) & " variable type" & @CRLF & _ "$fuUserFunc : " & @TAB & VarGetType( $fuUserFunc ) & " variable type" ) ; Loop While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete( $hGui ) EndFunc Func Test() EndFunc Run the script by double clicking. MsgBox output: Variable Types on Server $aArray : Array variable type $mMap : Map variable type $dBinary : Binary variable type $bBoolean : Bool variable type $pPtr : Ptr variable type $hWnd : Ptr variable type $iInt : Int32 variable type $fFloat : Double variable type $oObject : Object variable type $sString : String variable type $tStruct : DLLStruct variable type $vKeyword : Keyword variable type $fuFunc : Function variable type $fuUserFunc : UserFunction variable type Just leave the MsgBox running. Client.au3: #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y Opt( "MustDeclareVars", 1 ) #include <GUIConstantsEx.au3> ; IRunningObjectTable.au3 UDF ; not needed in the client. Client() Func Client() ; Error monitoring. This will trap all COM errors while alive. Local $oErrorHandler = ObjEvent( "AutoIt.Error", "COMerror" ) ; Get default ROT-object (Dict obj) Local $oDict = ObjGet( "DataTransferObject" ) Local $aArray = $oDict.Item( "$aArray" ), $aArrayErr = @error Local $mMap = $oDict.Item( "$mMap" ), $mMapErr = @error Local $dBinary = $oDict.Item( "$dBinary" ), $dBinaryErr = @error Local $bBoolean = $oDict.Item( "$bBoolean" ), $bBooleanErr = @error Local $pPtr = $oDict.Item( "$pPtr" ), $pPtrErr = @error Local $hWnd = $oDict.Item( "$hWnd" ), $hWndErr = @error Local $iInt = $oDict.Item( "$iInt" ), $iIntErr = @error Local $fFloat = $oDict.Item( "$fFloat" ), $fFloatErr = @error Local $oObject = $oDict.Item( "$oObject" ), $oObjectErr = @error Local $sString = $oDict.Item( "$sString" ), $sStringErr = @error Local $tStruct = $oDict.Item( "$tStruct" ), $tStructErr = @error Local $vKeyword = $oDict.Item( "$vKeyword" ), $vKeywordErr = @error Local $fuFunc = $oDict.Item( "$fuFunc" ), $fuFuncErr = @error Local $fuUserFunc = $oDict.Item( "$fuUserFunc" ), $fuUserFuncErr = @error ConsoleWrite( "Variable Types on Client" & @CRLF ) ConsoleWrite( "$aArray : " & ( $aArrayErr ? "@error = " & $aArrayErr : VarGetType( $aArray ) & " variable type" ) & @CRLF ) ConsoleWrite( "$mMap : " & ( $mMapErr ? "@error = " & $mMapErr : VarGetType( $mMap ) & " variable type" ) & @CRLF ) ConsoleWrite( "$dBinary : " & ( $dBinaryErr ? "@error = " & $dBinaryErr : VarGetType( $dBinary ) & " variable type" ) & @CRLF ) ConsoleWrite( "$bBoolean : " & ( $bBooleanErr ? "@error = " & $bBooleanErr : VarGetType( $bBoolean ) & " variable type" ) & @CRLF ) ConsoleWrite( "$pPtr : " & ( $pPtrErr ? "@error = " & $pPtrErr : VarGetType( $pPtr ) & " variable type" ) & @CRLF ) ConsoleWrite( "$hWnd : " & ( $hWndErr ? "@error = " & $hWndErr : VarGetType( $hWnd ) & " variable type" ) & @CRLF ) ConsoleWrite( "$iInt : " & ( $iIntErr ? "@error = " & $iIntErr : VarGetType( $iInt ) & " variable type" ) & @CRLF ) ConsoleWrite( "$fFloat : " & ( $fFloatErr ? "@error = " & $fFloatErr : VarGetType( $fFloat ) & " variable type" ) & @CRLF ) ConsoleWrite( "$oObject : " & ( $oObjectErr ? "@error = " & $oObjectErr : VarGetType( $oObject ) & " variable type" ) & @CRLF ) ConsoleWrite( "$sString : " & ( $sStringErr ? "@error = " & $sStringErr : VarGetType( $sString ) & " variable type" ) & @CRLF ) ConsoleWrite( "$tStruct : " & ( $tStructErr ? "@error = " & $tStructErr : VarGetType( $tStruct ) & " variable type" ) & @CRLF ) ConsoleWrite( "$vKeyword : " & ( $vKeywordErr ? "@error = " & $vKeywordErr : VarGetType( $vKeyword ) & " variable type" ) & @CRLF ) ConsoleWrite( "$fuFunc : " & ( $fuFuncErr ? "@error = " & $fuFuncErr : VarGetType( $fuFunc ) & " variable type" ) & @CRLF ) ConsoleWrite( "$fuUserFunc : " & ( $fuUserFuncErr ? "@error = " & $fuUserFuncErr : VarGetType( $fuUserFunc ) & " variable type" ) & @CRLF ) ConsoleWrite( @CRLF & "@error = -2147221163 = 0x80040155" & @CRLF & " Interface not registered" & @CRLF ) #forceref $oErrorHandler EndFunc Func COMerror() EndFunc Run the script in SciTE with F5. The object event message handler, $oErrorHandler, is used to set an error code in @error. Console output: Variable Types on Client $aArray : Array variable type $mMap : @error = -2147221163 $dBinary : Binary variable type $bBoolean : Bool variable type $pPtr : Int32 variable type $hWnd : Int32 variable type $iInt : Int32 variable type $fFloat : Double variable type $oObject : Object variable type $sString : String variable type $tStruct : @error = -2147221163 $vKeyword : Keyword variable type $fuFunc : @error = -2147221163 $fuUserFunc : @error = -2147221163 @error = -2147221163 = 0x80040155 Interface not registered There are 3 COM incompatible data types that all fail with error code 0x80040155, Interface not registered: Map, DllStruct and Function. An inspection of these data types with code in InspectVariable.au3 from Accessing AutoIt Variables gives this result: InspectVariable.txt: $mMap Type = Map ptr = 0x009B5FF8 ($pVariant) vt = 0x0024 (VT_RECORD, pointer to record object) data = 0x00000000 $tStruct Type = DLLStruct ptr = 0x009E3C08 ($pVariant) vt = 0x0024 (VT_RECORD, pointer to record object) data = 0x00000000 $fuFunc Type = Function ptr = 0x009E3C98 ($pVariant) vt = 0x0024 (VT_RECORD, pointer to record object) data = 0x00000000 $fuUserFunc Type = UserFunction ptr = 0x009E3C98 ($pVariant) vt = 0x0024 (VT_RECORD, pointer to record object) data = 0x00000000 In all cases the variant data type is VT_RECORD used for user defined types (UDTs) and the data field, which should be a pointer to the IRecordInfo interface, is a NULL pointer. It's thus not possible to obtain more information about these data types. At least not through the techniques in Accessing AutoIt Variables. The bottom line seems to be that the data types are coded through COM incompatible custom implementations in the AutoIt internal C/C++ code. AutoIt and Python Integration The rather elusive code box at top of this post nevertheless indicates how to access a ROT object in Python through the GetObject() function. This allows data to be exchanged between AutoIt and Python. But first Python must be installed. Python InstallationPython 3.8.0 is the latest version that can be installed on Windows 7. To avoid spending too much time on installation, it's easiest to just download the Windows x86-64 executable installer (python-3.8.0-amd64.exe) at bottom of the page and install Python from there. Make sure that the path to the Python installation folder is added to environment variables. Necessary for AutoIt commands like Run and RunWait to find Python.exe without specifying the full path, which can be different from one PC to another. Upgrade PIP package manager: C:\>py -m pip install --upgrade pip Install PyWin32 package to access the Windows API C:\>py -m pip install --upgrade pywin32 Install NumPy package with support for arrays and matrices C:\>py -m pip install --upgrade numpy AutoIt and PythonExamples\AutoItPython\ contains 3 small AutoIt scripts and 2 Python scripts for a simple demonstration of passing arrays back and forth between AutoIt and Python. Open a command prompt and run the 5 scripts in a similar way: C:\>d: D:\>cd D:\...\Examples\AutoItPython D:\...\Examples\AutoItPython>subst z: . D:\...\Examples\AutoItPython>z: Z:\>"0) Server.au3" Z:\>"1) AutoIt send.au3" Z:\>"2) Python rec.py" (123, 456.789, 'String') 123 <class 'int'> 456.789 <class 'float'> String <class 'str'> ((1, 2, 3, 4), (5, 6, 7, 8), (9, 10, 11, 12)) (1, 2, 3, 4) Z:\>"3) Python send.py" Z:\>"4) AutoIt rec.au3" Z:\>d: D:\...\Examples\AutoItPython>subst z: /d It should be enough to press 0+Tab to execute "0) Server.au3". Correspondingly for the other scripts. 0) Server.au3: #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y Opt( "MustDeclareVars", 1 ) #include <GUIConstantsEx.au3> #include "IRunningObjectTable.au3" Server() Func Server() ; Create a default ROT-object (Dictionary object) ; The script that creates the ROT object is the server ; The ROT object is available while the server is running Local $sDataTransferObject = "DataTransferObject" ROT_CreateDefaultObject( $sDataTransferObject, 0 ) ; 0 -> Non-unique ; Create server GUI Local $hGui = GUICreate( "Server", 200, 70, 200, 50 ) ; Show GUI GUISetState() ; Loop While 1 Switch GUIGetMsg() Case $GUI_EVENT_CLOSE ExitLoop EndSwitch WEnd GUIDelete( $hGui ) EndFunc 1) AutoIt send.au3: #AutoIt3Wrapper_Au3Check_Parameters=-d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y Opt( "MustDeclareVars", 1 ) Example() Func Example() ; Get default ROT-object (Dictionary object) Local $oDict = ObjGet( "DataTransferObject" ) ; Add 1d array to $oDict Local $aArray1 = [ 123, 456.789, "String" ] $oDict.Item( "aArray1" ) = $aArray1 ; Add 2d array to $oDict ; In AutoIt and Python, rows and columns are swapped ; The AutoIt array below will result in the following Python array ; aArray = [ [ 1, 2, 3, 4 ], [ 5, 6, 7, 8 ], [ 9, 10, 11, 12 ] ] Local $aArray2 = [ _ [ 1, 5, 9 ], _ [ 2, 6, 10 ], _ [ 3, 7, 11 ], _ [ 4, 8, 12 ] ] $oDict.Item( "aArray2" ) = $aArray2 EndFunc 2) Python rec.py: import win32com.client import numpy as np # Get default ROT-object (Dictionary object) oDict = win32com.client.GetObject( "DataTransferObject" ) # Get 1d AutoIt array as List aArray1 = oDict( "aArray1" ) print( aArray1 ) print( "" ) # Print data types for item in aArray1: print( "{}\t{}".format( item, type( item ) ) ) print( "" ) # Get 2d array as NumPy array np.aArray2 = oDict( "aArray2" ) print( np.aArray2 ) print( np.aArray2[0] ) These are the _ArrayDisplay's created by 4) AutoIt rec.au3: Prime NumbersExamples\Prime numbers\1) Scripts\ contains scripts to calculate prime numbers using AutoIt, Python and VB.NET. Run au3-scripts in SciTE with F5. pyPrimes.au3: #AutoIt3Wrapper_Au3Check_Parameters=-d -w- 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7 #AutoIt3Wrapper_UseX64=Y Opt( "MustDeclareVars", 1 ) #include "..\..\..\Includes\IRunningObjectTable.au3" #include "..\..\..\Includes\DataDisplay\Functions\ArrayDisplayEx\ArrayDisplayEx.au3" #include "..\..\..\Includes\DataDisplay\Functions\ArrayDisplayEx\ArrayDisplayEx_ColumnFormats.au3" ; Create a default ROT-object (Dictionary object) ; The script that creates the ROT object is the server ; The ROT object is available while the server is running Global $sDataTransferObject = "DataTransferObject" Global $oDict = ROT_CreateDefaultObject( $sDataTransferObject, 0 ) ; 0 -> Non-unique Example( 100 ) Example( 1000 ) Example( 10000 ) Func Example( $nPrimes ) Local $aAlignment = [ [ 0, "C" ], [ 1, "R" ] ] Local $aColWidthMin = [ [ 0, 65 ], [ 1, 80 ] ] Local $aColFormats = [ 0, "Int1000Sep", "," ] ; DATA SOURCE column index Local $aFeatures = [ [ "ColAlign", $aAlignment ], _ [ "ColWidthMin", $aColWidthMin ], _ [ "ColFormats", $aColFormats ], _ [ "1dColumns", 10 ] ] RunWait( "Python.exe pyPrimes.py " & """" & $nPrimes & """", "", @SW_HIDE ) Local $aPrimes = $oDict.Item( "aPrimes" ) _ArrayDisplayEx( $aPrimes, "Prime numbers", "#|Primes", 0, $aFeatures ) EndFunc pyPrimes.py: import sys import math as ma import numpy as np import win32com.client # Get default ROT-object (Dictionary object) oDict = win32com.client.GetObject( "DataTransferObject" ) def CalcPrimes( nPrimes ): # Define NumPy array to store prime numbers aPrimes = np.zeros( shape = ( nPrimes, ), dtype = np.int32 ) # Store first prime iPrime = 2 iPrimes = 0 aPrimes[iPrimes] = iPrime iPrimes += 1 iPrime += 1 # Calculate primes while iPrimes < nPrimes: i = 1 iMaxFactor = ma.ceil(ma.sqrt(iPrime)) while i < iPrimes and aPrimes[i] <= iMaxFactor: if ma.fmod( iPrime, aPrimes[i] ) == 0: i = iPrimes i += 1 if i < iPrimes + 1: aPrimes[iPrimes] = iPrime iPrimes += 1 iPrime += 2 oDict[ "aPrimes" ] = aPrimes CalcPrimes( int( sys.argv[1] ) ) RuntimesExamples\Prime numbers\2) Runtimes\ is a speed comparison of the 3 prime number calculations performed with the techniques in Runtimes and Speed Comparisons. Run Primes.au3 in SciTE with F5. Primes.txt: Calculation of Prime Numbers Calculation of Prime Numbers AutoIt vs Python vs VB.NET AutoIt vs Python vs VB.NET Code executed as 64-bit code Code executed as 64-bit code ================================== ================================== 100 prime numbers 100 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: 7.1752 AutoIt calculation: 1.8151 Python calculation: 339.0743 Python calculation: 312.9130 VB.NET calculation: 0.1008 VB.NET calculation: 0.0481 500 prime numbers 500 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: 16.3156 AutoIt calculation: 14.9084 Python calculation: 317.8483 Python calculation: 314.0434 VB.NET calculation: 0.1665 VB.NET calculation: 0.1207 1,000 prime numbers 1,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: 38.2239 AutoIt calculation: 40.0983 Python calculation: 345.3165 Python calculation: 318.2725 VB.NET calculation: 0.5128 VB.NET calculation: 0.2229 2,000 prime numbers 2,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: 108.7436 AutoIt calculation: 102.3103 Python calculation: 357.4340 Python calculation: 353.0137 VB.NET calculation: 0.7696 VB.NET calculation: 0.4523 5,000 prime numbers 5,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: 351.2818 AutoIt calculation: 355.7042 Python calculation: 418.0871 Python calculation: 404.9797 VB.NET calculation: 1.6748 VB.NET calculation: 1.3370 10,000 prime numbers 10,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: 919.5793 AutoIt calculation: 928.2449 Python calculation: 602.1903 Python calculation: 553.9019 VB.NET calculation: 3.9493 VB.NET calculation: 3.1382 20,000 prime numbers 20,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: 2365.4960 AutoIt calculation: 2378.4718 Python calculation: 1161.5604 Python calculation: 991.8602 VB.NET calculation: 9.8814 VB.NET calculation: 8.0775 50,000 prime numbers 50,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: 8748.3280 AutoIt calculation: 8598.7165 Python calculation: 3422.4653 Python calculation: 2717.4886 VB.NET calculation: 33.1839 VB.NET calculation: 27.4017 100,000 prime numbers 100,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: 22959.9331 AutoIt calculation: 22686.7254 Python calculation: 8589.2150 Python calculation: 6701.6450 VB.NET calculation: 83.8414 VB.NET calculation: 69.6644 250,000 prime numbers 250,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: >10000.0000 AutoIt calculation: >10000.0000 Python calculation: 30198.3188 Python calculation: 23837.4175 VB.NET calculation: 293.9497 VB.NET calculation: 235.9579 500,000 prime numbers 500,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: >10000.0000 AutoIt calculation: >10000.0000 Python calculation: >10000.0000 Python calculation: >10000.0000 VB.NET calculation: 765.3462 VB.NET calculation: 600.5832 750,000 prime numbers 750,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: >10000.0000 AutoIt calculation: >10000.0000 Python calculation: >10000.0000 Python calculation: >10000.0000 VB.NET calculation: 1346.5033 VB.NET calculation: 1051.7918 1,000,000 prime numbers 1,000,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: >10000.0000 AutoIt calculation: >10000.0000 Python calculation: >10000.0000 Python calculation: >10000.0000 VB.NET calculation: 2011.5523 VB.NET calculation: 1567.1886 2,500,000 prime numbers 2,500,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: >10000.0000 AutoIt calculation: >10000.0000 Python calculation: >10000.0000 Python calculation: >10000.0000 VB.NET calculation: 7297.9896 VB.NET calculation: 5667.4302 5,000,000 prime numbers 5,000,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: >10000.0000 AutoIt calculation: >10000.0000 Python calculation: >10000.0000 Python calculation: >10000.0000 VB.NET calculation: 19501.3542 VB.NET calculation: 15133.7115 10,000,000 prime numbers 10,000,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: >10000.0000 AutoIt calculation: >10000.0000 Python calculation: >10000.0000 Python calculation: >10000.0000 VB.NET calculation: >10000.0000 VB.NET calculation: >10000.0000 16,000,000 prime numbers 16,000,000 prime numbers ---------------------------------- ---------------------------------- AutoIt calculation: >10000.0000 AutoIt calculation: >10000.0000 Python calculation: >10000.0000 Python calculation: >10000.0000 VB.NET calculation: >10000.0000 VB.NET calculation: >10000.0000 The measurements in the left column are carried out on a Windows 7, medium, 6½ year old PC. The measurements on the right on a Windows 10, medium (high end), 1½ year old PC. A comparison of AutoIt and Python code shows that AutoIt performs best for a small number of prime numbers. This is due to an overhead when passing data from Python to AutoIt. When calculating about 7,500 prime numbers and higher, Python code becomes faster than AutoIt code. Up to about 3 times faster in these measurements. This is probably due to differences in AutoIt and Python code interpreters. The performance optimization when using real compiled VB.NET code is quite clear. Up to 100 and 300 times faster than Python and AutoIt code respectively. Both Python and VB.NET code perform about 25% better on newer hardware. AutoIt code shows the same performance on old and new hardware. The lack of optimization can probably only be attributed to the Windows 10 operating system. Python and VBScriptExamples\PythonVBScript\ shows the exchange of array data between Python and VBScript through a ROT object created by an AutoIt server. Note the simplicity of the code. Open a command prompt and run the 5 scripts in a similar way: C:\>d: D:\>cd D:\...\Examples\PythonVBScript D:\...\Examples\PythonVBScript>subst z: . D:\...\Examples\PythonVBScript>z: Z:\>"0) Server.au3" Z:\>"1) Python send.py" Z:\>"2) VBScript rec.vbs" Z:\>"3) VBScript send.vbs" Z:\>"4) Python rec.py" (123, 456.789, 'String') 123 <class 'int'> 456.789 <class 'float'> String <class 'str'> Z:\> Z:\>d: D:\...\Examples\PythonVBScript>subst z: /d 1) Python send.py: import win32com.client # Get default ROT-object (Dictionary object) oDict = win32com.client.GetObject( "DataTransferObject" ) # Add 1d List to oDict aArray1 = [ 123, 456.789, "String" ] oDict[ "aArray1" ] = aArray1 2) VBScript rec.vbs: 'Get default ROT-object (Dictionary object) Set oDict = GetObject( "DataTransferObject" ) aArray1 = oDict( "aArray1" ) MsgBox( "aArray1(0) = " & aArray1(0) & vbTab & vbTab & "Variant type = " & VarType( aArray1(0) ) & " (vbLong)" & vbCrLf & _ "aArray1(1) = " & aArray1(1) & vbTab & "Variant type = " & VarType( aArray1(1) ) & " (vbDouble)" & vbCrLf & _ "aArray1(2) = " & aArray1(2) & vbTab & vbTab & "Variant type = " & VarType( aArray1(2) ) & " (vbString)" & vbCrLf ) This is the MsgBox created by 2) VBScript rec.vbs: 7z-file The 7z-file contains source code for UDFs and examples You need AutoIt 3.3.16.1 or later. Tested on Windows 7 and Windows 10. Comments are welcome. Let me know if there are any issues. AutoItPython.7z3 points
-
How to check if exemple.au3 is running
SkysLastChance and one other reacted to Jos for a topic
There are several ways you can check. One could be to set the title of the Hidden AutoIt3 Window to something unique per script and test for the existence of that hidden window. ; put this in script one at the start somewhere AutoItWinSetTitle("Script-one") ; Add this test in the Master script If WinExists("Script-one") then ; logic here EndIf .... but guess you could also get this to work with _Singleton(), so show us an example of your implementation that's not working.2 points -
Version 1.6.3.0
17,278 downloads
Extensive library to control and manipulate Microsoft Active Directory. Threads: Development - General Help & Support - Example Scripts - Wiki Previous downloads: 30467 Known Bugs: (last changed: 2020-10-05) None Things to come: (last changed: 2020-07-21) None BTW: If you like this UDF please click the "I like this" button. This tells me where to next put my development effort1 point -
ListView export speed
pixelsearch reacted to Skysnake for a topic
_GUICtrlListView_BeginUpdate($ListView) Do not underestimate the value of wrapping ListView populate / delete functions in _GUICtrlListView_BeginUpdate and _GUICtrlListView_EndUpdate I had a Listview with 6000+ lines of data, took ~ 60 seconds / 1000 lines of data (very slow). Wrapping both the data add, and the _GUICtrlListView_DeleteAllItems in _GUICtrlListView_BeginUpdate reduced the total time to delete and re-populate to ~90 seconds (acceptable)1 point -
I want to replace files in Folders in other Folders
SOLVE-SMART reacted to ioa747 for a topic
For me, the text inside the text file has changed in all the files. the name is the same, of course FileCopy ( "source", "dest" [, flag = 0] )1 point -
Human like mouse movement script
pixelsearch reacted to Musashi for a topic
Not necessarily. Within SciTE you can open a window using SHIFT F8. There you can enter command line parameters (even several in one line). This is helpful during development. The parameters set are preserved during the SciTE session.1 point -
I want to replace files in Folders in other Folders
SOLVE-SMART reacted to ioa747 for a topic
take a look to FileFindFirstFile and to _FileListToArray examples in your help file1 point -
Learning other languages
SanityChecker reacted to SOLVE-SMART for a topic
Hi @SanityChecker, this is indeed a interesting question, because it depends on what you want to do or plan to do now and in the future. Personally I can suggest GO (Go lang) and Lua besides AutoIt 😀 . With Go you can handle almost everything in a more scripting way of programming (like AutoIt), but of course with many common (modern) design patterns and good practices. It's also not the badest choice when it comes to handling WEB stuff. Lua is also pretty nice, but not really a substitute for JavaScript (Typescript) and node.js. I guess if you really want to do more frontend related programs, node.js is a proper way to go. Otherwise you can have a look at Deno as a substitute for node.js. C# would also fulfill almost ever needs, but the syntax is quite different (if you're looking for similarities to AutoIt). 💡 My personal conclusion: If you are not depending on trends or the biggest support base like you would have with C# (.NET), then go with GO (Go lang) 😅 . I am sure several folks here will recommend different languages, because it really depends on you and the "now" and the "future". Best regards Sven1 point -
ListView export speed
Skysnake reacted to pixelsearch for a topic
Hi everybody Even if they're not recent, both following links are interesting if you want to know how to improve speed in your listview control : https://www.autoitscript.com/forum/topic/67829-_guictrllistview_additem-much-slower-than-guictrlcreatelistviewitem/ https://www.autoitscript.com/forum/topic/132703-correct-way-to-clear-a-listview-solved/ Also LarsJ , in this thread, wrote what follows : "A general approach to listviews is to create listview and listview items with native functions due to speed and then use UDF functions for everything else." I'd like to add 2 comments based on the little experience I got with my "CSV file editor" script : 1) If the data you need to populate your listview is contained in an array, then do not use the native function GUICtrlCreateListViewItem() in a loop, but choose instead the function _GUICtrlListView_AddArray() This function, found in GuiListView.au3 and written by Paul Campbell & Gary Frost is optimized and its speed will be 3 times faster than a loop with many GUICtrlCreateListViewItem() needed to populate the listview. Why is it faster ? Because there's a loop on items & subitems, the loop is included in the function and the buffer involved is opened only once. That's the reason why the next release of "CSV file editor" will be based on _GUICtrlListView_AddArray() instead of GUICtrlCreateListViewItem(), which will allow to populate the listview 3 times faster during the import phase (tests done successfully on arrays of 1000, 10000, 36000 rows) 2) Now let's talk about deleting all items in a listview : => if you added your items with GUICtrlCreateListViewItem() then deleting thousands of items will take a lot of time because each control has to be deleted one by one in a loop, using GuiCtrlDelete() as explained by Gary Frost himself, here => if you added your items with _GUICtrlListView_AddArray() then deleting all items could be done in a snap, like this : $g_idListView = GUICtrlCreateListView(...) ; native-created listview $g_hListView = GuiCtrlGetHandle($g_idListView) _GUICtrlListView_AddArray($g_idListview, ...) ; populating listview (fastest way) _SendMessage($g_hListView, $LVM_DELETEALLITEMS) ; fast deletion + no id's leaks So, if you are sure that your listview items are not native, then you don't need to call _GUICtrlListView_DeleteAllItems() . Just Send the Message $LVM_DELETEALLITEMS and avoid the loop found in _GUICtrlListView_DeleteAllItems() which would inspect each item to know if it's native or not (you know they are not !) A worse idea would be to call _SendMessage($g_hListView, $LVM_DELETEALLITEMS) when all your items are natively created with GUICtrlCreateListViewItem() . Why is that ? Because though deletion appears fast on your monitor, AutoIt will not delete any of the thousands of items controls id's and you'll end with plenty of handle leaks. Have a look at BrewManNH's post, which explains the situation. And even if "we can have up to 64k control ids", imagine a user doing this in the same session : * 1st file imported in listview, 30.000 items, using GUICtrlCreateListViewItem() * Delete them all with _SendMessage($g_hListView, $LVM_DELETEALLITEMS), bad way * Now Autoit would (for example) assign a control id of 30.027 for any new control created * 2nd file imported in listview, 30.000 items, using GUICtrlCreateListViewItem() * Delete them all... and you already reached 60.000 id's all "alive" for AutoIt None of this happens the other way, which is : * 1st file imported in listview, 30.000 items, using _GUICtrlListView_AddArray() * Delete them all with _SendMessage($g_hListView, $LVM_DELETEALLITEMS), good way * Now Autoit would (for example) assign a control id of 27 for any new control created, great * 2nd file imported in listview, 30.000 items, using _GUICtrlListView_AddArray() * Delete them all... and your new controls id would still start at 27, no leak. My conclusion (for now) : _GUICtrlListView_AddArray() rules for both reasons described above1 point -
You are right about leaking, anyway I use it that way too. If you want fix leaking then use _GUICtrlListView_AddItem() instead of GUICtrlCreateListViewItem() This way there is no ControlID created but creating listview items by UDF instead of native GUICtrlxxx is slower..1 point
-
Because deleting the items from the LV with the Control ID takes a lot longer because it deletes the controls 1 at a time in a loop. With the handle it deletes them all at once.1 point
-
Retrieve the handle of the ListView using GUICtrlGetHandle($iListView) and then use the handle with _GUICtrlListView_DeleteAllItems()1 point