Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 10/28/2021 in all areas

  1. RTFC

    I need help

    How very interesting. You know what I need? I need forum users who: create threads with informative titles use acceptable font sizes show evidence of their own efforts to achieve a specific task provide a minimally-sized example script illustrating the perceived problem/error/misunderstanding keep in mind that this is not a script-ordering service, but totally free advice provided by volunteers Welcome to the AutoIt forums, but please try harder next time you post. Thanks.
    9 points
  2. You could also write out to the Event Viewer when your script completes. Good not only for keeping track of the number of times run, but also polling for failures.
    2 points
  3. Werty

    I need help

    It's very often google translate's fault that new members seems impolite, especially with Asian members, as Asian's speaks differently than we do in the western world, saying "Write me code now, yes" is perfectly normal for an asian, in their own language/culture, but we dont understand it, and google translate certainly doesnt.
    2 points
  4. LarsJ

    ObjGet failed why?

    Probably because the VBScript function GetObject() and the AutoIt function ObjGet() don't work in exactly the same way. Note that this VBScript code also works: Set oGetobj = GetObject("", "Scripting.FileSystemObject") WScript.Echo TypeName(oGetobj) GetObject() can thus create a new object if the parameters don't refer to an existing object. The way you execute GetObject() in your VBScript code, the function creates a new object because the parameters don't match an existing object. In your code, the two objects are different objects but of the same type. The AutoIt ObjGet() function doesn't create new objects. It only creates a reference to an existing object through a file name or a line in the Running Object Table (ROT). These two options are both demonstrated in the examples in the help file. ObjCreate("Scripting.FileSystemObject") in AutoIt doesn't create an object that can be referenced either through a file name or through the ROT. Therefore, ObjGet() fails. CreateObject("Scripting.FileSystemObject") in VBScript also doesn't create an object that can be referenced either through a file name or through the ROT. But GetObject() doesn't fail because in this situation it creates a new object.
    2 points
  5. jchd

    HMI

    You need to dig into the DWIN website which offers support for their tablet to understand that this piece of hardware is just a generic SOC tablet with interfaces provided to manage external devices. If the original board is toast it's utterly probable you won't be able to copy back all the data you need (config file, icons, images, ...). For that ask the pool heater maker (Astral) if they are willing to provide you with an SD card filled with all the required resources for your pool heater model, plus the procedure to load that content on the new tablet. Note that this subject has zero relationship to AutoIt and I wonder why you ask this question here.
    2 points
  6. [NEW VERSION] - 17 Mar 22 Added: A new function _Notify_Size which allows you to adjust the size of the notification from its default 160x40. Please read the function header to see the max/min sizes that you can set for the width and height - the function returns informative @error/@extended values if these are not respected. Regardless of the size set, each notification will still display only 2 lines of text with the size of font used set automatically by the UDF. New UDF in the zip below. Previous changes: Changelog.txt A while ago I was asked to help port an AHK UDF to AutoIt. This was not too difficult and I found it useful myself (as a replacement for ConsoleWrite when debugging compiled scripts among other things). I have been polishing it for a while and thought I might release it in case it proves useful to anyone else. The notifications produced by Notify are small 2-line boxes that pop out of the edge of the display one above the other (you can select which side and in which direction they appear) - you can have as many as you want although only as many as can fit on your display will appear, the others will appear as soon as there is room. You can select whether they will retract after a certain time and/or when clicked. Colours and font are user-definable, and you can add an icon or image (bmp, jpg, gif or png) if you wish. When a notification retracts, the others move to leave space for more (you can select a smoooth slide or an instant move) - run the examples to see them in action. If you find the default sizing of the notifications is not to your liking you can change it by amending these values in the UDF (lines #354-356): ; Set default auto-sizing Notify dimensions Local $iNotify_Width_max = 300 Local $iNotify_Width_min = 150 Local $iNotify_Height = 40 A zip containing the UDF, example scripts and my StringSize UDF (which is also required): Notify.zip As usual happy for comments and/or compliments. M23
    1 point
  7. The .NET IntPtr type is useful for copying data in the form of memory blocks between managed .NET code and unmanaged AutoIt code. An advantage of using this technique is that the data copying isn't subject to internal AutoIt COM conversions. This means that even copying large memory blocks can be done very fast. A disadvantage is that such memory blocks can only be handled through DllStructs in AutoIt, unless the memory blocks can be used directly eg. if they represent image data. Another technique for passing data between AutoIt and C#/VB.NET is demonstrated in Using C# and VB Code. With this technique, variables and arrays are exchanged through comparable COM data types. Eg. passing an AutoIt array to .NET as a safearray of variants. On the AutoIt side the safearray of variants is created through internal AutoIt COM conversions. On the .NET side data is received as an array of objects. Although the COM conversions are performed by internal AutoIt functions as compiled C/C++ code, the conversions take some time for large arrays. Since AutoIt arrays are limited to 2^24 = 16,777,216 elements, this is the maximum amount of data that can be passed at one time. DotNetAll.au3 UDFCommon to the two techniques is that they are both based on DotNetAll.au3 UDF (contained in the 7z-file below). The DotNetAll.au3 UDF is by far the easiest way to execute compiled and multi-threaded code in AutoIt through C# or VB.NET code, thereby managing bottlenecks in the AutoIt code. With this new IntPtr data copying technique, it's possible to handle more bottlenecks than can be handled with the existing COM data passing technique. The benefits of the DotNetAll.au3 UDF are: The .NET source code can be easily written in SciTE without the need for a specific development tool The .NET code is compiled and executed directly in your AutoIt script, where you apply the code If the AutoIt script is run in SciTE with F5, .NET error messages appear in the console The .NET code can be easily distributed in the form of source files (text files) You avoid the registration/unregistration tyranny of .NET assembly Dll files Although DotNetAll.au3 UDF contains a lot of code, it's a complete UDF in the way that you can concentrate on the main functions. There's no need to go through all the details of the code. There are two main functions in the UDF. A function for loading C#/VB.NET code and a function for creating an object based on the C#/VB.NET class. In AutoIt, the functions are used as follows: Local $oNetCode = DotNet_LoadVBcode( FileRead( "Example01.vb" ), "System.dll" ) ; Load VB.NET code Local $oNetCode = DotNet_LoadCScode( FileRead( "Example02.cs" ), "System.dll" ) ; Load C# code Local $oTestClass = DotNet_CreateObject( $oNetCode, "TestClass" ) ; Create object Then just call the object methods and get/set the object properties. This is demonstrated in the examples below. ExamplesThe examples can be found in the Examples folder. All examples use the DotNetAll.au3 UDF, which is located in the Includes folder. It's the only file in Includes. Only the Introductory examples demonstrates C# code. Since VB.NET code is most easily accessible with an AutoIt background, the rest of the examples are shown only as VB.NET code. Note that in all examples, all memory allocation and all data copying is performed exclusively in the .NET code. Run the examples with F5 in SciTE. Memory Access Violation error The Introductory examples and Performance measurements all caused a Memory Access Violation error and a consequent crash in the first version of the examples when executed on Windows 10 as 64 bit code. This is because the IntPtr data type isn't handled correctly in AutoIt on Windows 10 as 64 bit code. This applies to all AutoIt versions including the current beta. The usual workaround is to return the IntPtr as a string. This error occurs when IntPtr is a void memory pointer. However, the error does not occur if IntPtr refers to a memory block that represents a valid handle or HWnd memory block. This is because a handle and HWnd pointer by Microsoft definition is a 4 byte pointer in both 32 and 64 bit code. In 64 bit code, the 4 most significant bytes are therefore all zeros. Thus, there are no errors in the Image manipulation examples. The function definition and return lines therefore looks like this in the published version in the 7z-file of the Introductory examples and Performance measurements (VB.NET code): Public Function Test() As String ... Return pnt.ToString() And look like this in Image manipulation examples (VB.NET code): Public Function Test() As IntPtr ... Return hBitmap Introductory examplesWith the IntPtr technique, part of the code is based on the .NET Marshal Class. The introductory examples in \1) Examples\ demonstrate how to apply this class. Example01.au3 and Example01.vb show how to copy a memory block of 16 bytes from VB.NET to AutoIt: #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\DotNetAll.au3" Example() Func Example() ; Load .NET code, create object, execute method Local $oNetCode = DotNet_LoadVBcode( FileRead( "Example01.vb" ), "System.dll" ) Local $oTestClass = DotNet_CreateObject( $oNetCode, "TestClass" ) Local $pPtr = $oTestClass.Test() ; View data as a DllStruct of Bytes Local $tBytes = DllStructCreate( "byte[16]", $pPtr ) ; Display data For $i = 1 To 16 ConsoleWrite( StringFormat( "$tBytes[%2s]", $i ) & StringFormat( " = %3s", DllStructGetData( $tBytes, 1, $i ) ) & @CRLF ) Next EndFunc Imports System Imports System.Runtime.InteropServices Class TestClass Public Function Test() As String 'Create and fill aArray with values 97 - 112 Dim aArray(15) As Byte For i As Integer = 0 To 15 aArray(i) = i + 97 Next 'Allocate memory in unmanaged AutoIt code Dim size As Integer = Marshal.SizeOf( aArray(0) ) * aArray.Length Dim pnt As IntPtr = Marshal.AllocHGlobal( size ) 'Copy from VB.NET to AutoIt 'Copy data to unmanaged memory Marshal.Copy( aArray, 0, pnt, aArray.Length ) 'Return memory pointer to AutoIt Return pnt.ToString() End Function End Class Example02.cs is a C# version of the same code: using System; using System.Runtime.InteropServices; class TestClass { public String Test() { // Create and fill aArray with values 97 - 112 byte[] aArray = new byte[16]; for( int i = 0; i < 16; i++ ) { aArray[i] = (byte)(i+97); } // (byte) => cast to byte // Allocate memory in unmanaged AutoIt code int size = Marshal.SizeOf( aArray[0] ) * aArray.Length; IntPtr pnt = Marshal.AllocHGlobal( size ); // Copy from C# to AutoIt // Copy data to unmanaged memory Marshal.Copy( aArray, 0, pnt, aArray.Length ); // Return memory pointer to AutoIt return pnt.ToString(); } } The code in Example02.au3 is the same as the code in Example01.au3. Example03.au3, Example03.vb and Example04.cs show how to copy a memory block of 16 bytes from AutoIt to VB.NET/C#. Performance measurementsExample01.au3 in \2) Runtimes\ calls the same Example() function 4 times: #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\DotNetAll.au3" Example( 1000000, True ) ; 1,000,000 Example( 1000000 ) ; 1,000,000 Example( 16777216 ) ; 16,777,216 = 2^24 Example( 100000000 ) ; 100,000,000 Func Example( $iInts, $bDisplay = False ) ; Load .NET code, create object Local $oNetCode = DotNet_LoadVBcode( FileRead( "Example01.vb" ), "System.dll" ) Local $oTestClass = DotNet_CreateObject( $oNetCode, "TestClass" ) ; Pass number of integers to VB.NET code $oTestClass.Test0( $iInts ) ; Create and fill VB.NET integer aArray with $iInts elements ; Allocate memory through managed VB.NET code Local $pPtr = $oTestClass.Test1() ; Copy $iInts integers from .NET aArray to AutoIt Local $hTimer = TimerInit() $oTestClass.Test2() ConsoleWrite( @CRLF & "Time to copy " & StringRegExpReplace( $iInts, "(\d{1,3}(?=(\d{3})+\z)|\d{3}(?=\d))", "\1" & "," ) & _ " integers from .NET aArray to AutoIt" & ( $bDisplay ? " = " : " = " ) & TimerDiff( $hTimer ) & @CRLF ) $hTimer = 0 ; View aArray data as a DllStruct of Bytes Local $tUints = DllStructCreate( "uint[" & $iInts & "]", $pPtr ) ; Display data If $bDisplay Then For $i = $iInts/2 To $iInts/2+16 ConsoleWrite( "$tUints[" & $i & "]" & " = " & DllStructGetData( $tUints, 1, $i+1 ) & @CRLF ) Next ConsoleWrite( @CRLF ) EndIf ; Copy $iInts integers from AutoIt to .NET aArray2 $hTimer = TimerInit() $oTestClass.Test3() ConsoleWrite( "Time to copy " & StringRegExpReplace( $iInts, "(\d{1,3}(?=(\d{3})+\z)|\d{3}(?=\d))", "\1" & "," ) & _ " integers from AutoIt to .NET aArray2 = " & TimerDiff( $hTimer ) & @CRLF ) $hTimer = 0 ; Display aArray2 data If $bDisplay Then $oTestClass.Test4() If $iInts <= 16777216 And Not $bDisplay Then Local $aArray2 ; Pass $iInts integers from .NET aArray2 to AutoIt $aArray2 ; .NET aArray2 is returned from a method directly into AutoIt $aArray2 ; In this way aArray2 is passed as a safearray of integers through default marshalling ; Internal AutoIt COM conversions of the safearray converts it to a native AutoIt array $hTimer = TimerInit() $aArray2 = $oTestClass.Test5() ConsoleWrite( @CRLF & "Time to pass " & StringRegExpReplace( $iInts, "(\d{1,3}(?=(\d{3})+\z)|\d{3}(?=\d))", "\1" & "," ) & _ " integers from .NET aArray to AutoIt $aArray2 = " & TimerDiff( $hTimer ) & @CRLF ) $hTimer = 0 ; Pass $iInts integers from AutoIt $aArray2 to .NET aArray3 ; AutoIt $aArray2 is passed as a function parameter directly into .NET aArray3 ; Internal AutoIt COM conversions pass $aArray2 as a safearray of variants with variant type integer ; The safearray of variants is passed to .NET through default marshalling as an array of objects with object type integer $hTimer = TimerInit() $oTestClass.Test6( $aArray2 ) ConsoleWrite( "Time to pass " & StringRegExpReplace( $iInts, "(\d{1,3}(?=(\d{3})+\z)|\d{3}(?=\d))", "\1" & "," ) & _ " variants from AutoIt $aArray2 to .NET aArray3 = " & TimerDiff( $hTimer ) & @CRLF ) $hTimer = 0 EndIf ConsoleWrite( @CRLF ) EndFunc Imports System Imports System.Runtime.InteropServices Class TestClass 'Globals in class Dim pnt As IntPtr Dim iInts As Integer Dim aArray() As Integer Dim aArray2() As Integer Public Sub Test0( iElements As Integer ) 'Get number of integers iInts = iElements ReDim aArray( iInts-1 ) ReDim aArray2( iInts-1 ) End Sub Public Function Test1() As String 'Create and fill integer aArray with iInts elements For i As Integer = 0 To iInts-1 aArray(i) = i Next 'Allocate memory in unmanaged AutoIt code Dim size As Integer = Marshal.SizeOf( aArray(0) ) * aArray.Length pnt = Marshal.AllocHGlobal( size ) 'Return memory pointer to AutoIt Return pnt.ToString() End Function Public Sub Test2() 'Copy iInts integers from .NET aArray to AutoIt Marshal.Copy( aArray, 0, pnt, aArray.Length ) End Sub Public Sub Test3() 'Copy iInts integers from AutoIt to .NET aArray2 Marshal.Copy( pnt, aArray2, 0, iInts ) End Sub Public Sub Test4() 'Display aArray2 data For i As Integer = iInts/2 To iInts/2+15 Console.WriteLine( "aArray2({0}) = {1}", i, aArray2(i) ) Next End Sub Public Function Test5() As Integer() 'Pass iInts integers from .NET aArray2 to AutoIt Return aArray2 End Function Public Sub Test6( aArray3 As Object() ) 'Pass iInts variants from AutoIt to .NET aArray3 Dim iLength As Integer = aArray3.Length 'Console.WriteLine( "iLength = {0}", iLength ) End Sub End Class In the first example, time measurements are made and a few data are printed in the console. In the other 3 examples, only time measurements are performed. The text box below is console output for these 3 examples. The "copy" lines are time measurements for the new IntPtr data copying technique. The "pass" lines are time measurements for the old COM data passing technique. Time to copy 1,000,000 integers from .NET aArray to AutoIt = 1.72992070180921 Time to copy 1,000,000 integers from AutoIt to .NET aArray2 = 1.72077794345564 Time to pass 1,000,000 integers from .NET aArray to AutoIt $aArray2 = 45.4910409279733 Time to pass 1,000,000 variants from AutoIt $aArray2 to .NET aArray3 = 218.360099451047 Time to copy 16,777,216 integers from .NET aArray to AutoIt = 19.8287034959137 Time to copy 16,777,216 integers from AutoIt to .NET aArray2 = 23.0162015219091 Time to pass 16,777,216 integers from .NET aArray to AutoIt $aArray2 = 743.615722663014 Time to pass 16,777,216 variants from AutoIt $aArray2 to .NET aArray3 = 4165.03925567973 Time to copy 100,000,000 integers from .NET aArray to AutoIt = 118.826768001676 Time to copy 100,000,000 integers from AutoIt to .NET aArray2 = 115.565850855568 The results clearly show that the new copying technique is much faster than the old passing technique. In particular, passing arrays from AutoIt to .NET is slow with the old technique. With the new technique, very large amounts of data can be copied. The reason for the slow passing of AutoIt arrays to .NET is that AutoIt arrays can only be passed as safearrays of variants. And passing variants is time consuming. Not at least due to internal AutoIt COM conversions which perform a by value copy of all AutoIt array elements into variant structures in the safearray. Image manipulationExample01.au3 and Example01.vb in \3) Images\ shows how to load an image in VB.NET and display the image in AutoIt: #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 <GDIPlus.au3> #include <GUIConstantsEx.au3> #include "..\..\Includes\DotNetAll.au3" Example() Func Example() ; Load .NET code, create object, execute method Local $oNetCode = DotNet_LoadVBcode( FileRead( "Example01.vb" ), "System.dll | System.Drawing.dll" ) Local $oTestClass = DotNet_CreateObject( $oNetCode, "TestClass" ) Local $pBitmap = $oTestClass.Test() ; Create GUI Local $hGui = GUICreate( "GDI+ Through .NET", 240, 164 ) GUISetState( @SW_SHOW ) ; Initialize GDI+ _GDIPlus_Startup() ; Draw bitmap to GUI Local $hBitmap = _GDIPlus_BitmapCreateFromHBITMAP( $pBitmap ) Local $hGraphic = _GDIPlus_GraphicsCreateFromHWND( $hGui ) _GDIPlus_GraphicsDrawImage( $hGraphic, $hBitmap, 0, 0 ) ; Clean up resources _GDIPlus_GraphicsDispose( $hGraphic ) _GDIPlus_BitmapDispose( $hBitmap ) _WinAPI_DeleteObject( $pBitmap ) ; Shut down GDI+ _GDIPlus_Shutdown() ; Loop Do Until GUIGetMsg() = $GUI_EVENT_CLOSE EndFunc Imports System Imports System.Drawing Class TestClass Public Function Test() As IntPtr 'Create a bitmap Dim bmp As New Bitmap( "Test.bmp" ) 'Create a GDI bitmap Dim hBitmap As IntPtr = bmp.GetHbitmap() 'Return GDI bitmap Return hBitmap End Function End Class Note that at the bottom of Example01.vb, the GDI bitmap pointer (hBitmap) is passed directly from VB.NET to AutoIt without a copy of the corresponding memory block. This is because the memory layout for a GDI bitmap memory block is the same in .NET and AutoIt. The same GDI bitmap memory block can without any further be used in both .NET and AutoIt. Without data copying, the code is very fast. Example02.au3 (same as Example01.au3) and Example02.vb is an example of real image manipulation. However, simple image manipulation. It's the same image as above, which is a 24 bpp (bits per pixel) image. 8 bits or 1 byte is used per RGB color. In the example, all the red bytes are set to the value 255 so that the whole image gets a red expression. Imports System Imports System.Drawing Imports System.Drawing.Imaging Imports System.Runtime.InteropServices Class TestClass Public Function Test() As IntPtr 'Create bitmap Dim bmp As New Bitmap( "Test.bmp" ) 'Lock the bits in the bitmap Dim rect As New Rectangle( 0, 0, bmp.Width, bmp.Height ) Dim bmpData As BitmapData = bmp.LockBits( rect, ImageLockMode.ReadWrite, bmp.PixelFormat ) 'Get the address of the first line Dim ptr As IntPtr = bmpData.Scan0 'Declare an array to hold the bytes of the bitmap 'This code is specific to a bitmap with 24 bits per pixel (bpp) Dim iBytes As Integer = Math.Abs( bmpData.Stride ) * bmp.Height Dim aRGBValues(iBytes-1) As Byte 'Copy the RGB values into the array Marshal.Copy( ptr, aRGBValues, 0, iBytes ) 'Set every third value to 255, a 24bpp image will look red For i As Integer = 2 To aRGBValues.Length - 1 Step 3 aRGBValues(i) = 255 Next 'Copy the RGB values back to the bitmap Marshal.Copy( aRGBValues, 0, ptr, iBytes ) 'Unlock the bits bmp.UnlockBits( bmpData ) 'Create GDI bitmap Dim hBitmap As IntPtr = bmp.GetHbitmap() 'Return GDI bitmap Return hBitmap End Function End Class Posts below Post 2 and the following posts is a discussion of the possibilities of executing PowerShell commands and scripts directly in AutoIt, and returning PowerShell output back to AutoIt. This is possible through C# code that acts as a host to execute PowerShell commands and scripts. C# Pointers demonstrates the use of pointers to performance optimize C# code. Use of structures to transfer data between AutoIt and .NET. Struct arrays in .NET code 7z-fileThe 7z-file contains source code for UDFs and examples. You need AutoIt 3.3.12 or later. Tested on Windows 7 and Windows 10. Comments are welcome. Let me know if there are any issues. DotNetIntPtr.7z
    1 point
  8. JLogan3o13

    I need help

    Not sure how Google translator accounts for him showing no effort.
    1 point
  9. Did you try restarting SciTE?
    1 point
  10. [NEW VERSION] - 26 Oct 21 Changed: Retracting multiple notifications in close succession could lead to a fatal "array subscript out of bounds" error - added a check to prevent this. New UDF in the first post. M23
    1 point
  11. jchd

    HMI

    Two functionally equivalent boards may use very different designs. If the chineesium board is a copy it may be incompatible with the origin board and run its own, proprietary firmware. It all depends if the two boards are exactly the same (manufacturer, model, version) AND if the board has provision to load/update the firmware. In general a SD card is used to load/store data, not host the firmware: that's typically stored in micro-controler flash (program) memory. The link you provide requires signing/login; no thanks.
    1 point
  12. ConsoleWrite("Exit is crazy"^0 & @CRLF)
    1 point
×
×
  • Create New...