Sign in to follow this
Followers
0

.NET compiled dll assembly in AutoIt, the simple approach!
By
guinness, in AutoIt Example Scripts
-
Recently Browsing 0 members
No registered users viewing this page.
-
Similar Content
-
By Colduction
Hello again, i have a code that changes username to favorite, my problem is how to use ObjEvent() function to catchĀ errors, i've red Help File and Forum's Topics but i can't understand too muchš
Here is aĀ code (I've copied thisĀ codes from a user of AutoIt Forum):
Ā
$sOldUser = "Administrator" $sNewUser = "Admin" $oUser = ObjGet("WinNT://" & @ComputerName & "/" & $sOldUser & ",user") $oComputer = ObjGet("WinNT://" & @ComputerName) $oNewUser = $oComputer.MoveHere($oUser.ADsPath, $sNewUser) Thanks for your care, I'm new to AutoIt and days should be passed with my coding and practicing to don't bother you :)ā¤
-
By buymeapc
Hello,
I was looking for a way to use the CLR functions to check a SQL 2016 database state, but I've been unable to find an example that I can get to work. Any help would be appreciated. Here's what I have, which always errors when I try to set the connection string and I'm not sure why. Thanks!
#include ".\Includes\CLR.au3" #include ".\Includes\CLR Constants.au3" JustATest() Func JustATest() Local $oAssembly = _CLR_LoadLibrary("System.Data") ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF) Local $oSQLConn = _CLR_CreateObject($oAssembly, "System.Data.SqlClient.SqlConnection") ConsoleWrite("$oSQLConn: " & IsObj($oSQLConn) & @CRLF) $oSQLConn.ConnectionString = "Server=serverip;Database=dbname;UID=user;PWD=aaaa;" $oSQLConn.Open EndFunc Edit: I am using ptrex's CLR UDF from here:
-
By ScrapeYourself
I didn't like the search time of Simple Native Image Search, and being on windows 10 64bit, I couldn't get ImageSearchDll.dll to work properly.
So I started researching image search routines and found this excellent post and set of repliesĀ find-a-bitmap-within-another-bitmap.
I really liked the pattern that the Simple Native Image Search used, theĀ clipboard usage and the method of searching. Although I think it could be improved by using some short circuit techniques to return sooner, likeĀ consecutive matchedĀ > 65% return | matched total > 85% return)Ā , and I wanted the function to manage the click on the found image as well.
So I justĀ did a bit more research and a few trips to MSDN and stackoverflow, these two snippets allow me to replicate KyleJustKnows code, and click.Ā Another feature is that it also saves the image it captures to disk, so that if the image is not found you can check what was captured, and alternatively cut out a new search image to use.
private void PrintScreen() { keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_EXTENDEDKEY, 0); keybd_event(VK_SNAPSHOT, 0, KEYEVENTF_KEYUP, 0); } public Bitmap CaptureScreenPrtSc() { PrintScreen(); if (Clipboard.ContainsImage()) { using (Image img = Clipboard.GetImage()) { img.Save("ClipBoard.PNG", ImageFormat.Png); return new Bitmap(img); } } return default; } [DllImport("user32.dll")] [return: MarshalAs(UnmanagedType.Bool)] private static extern bool GetCursorPos(out MousePoint lpMousePoint); [DllImport("user32.dll")] private static extern void mouse_event(int dwFlags, int dx, int dy, int dwData, int dwExtraInfo); private MousePoint GetCursorPosition() { var gotPoint = GetCursorPos(out MousePoint currentMousePoint); if (!gotPoint) { currentMousePoint = new MousePoint(0, 0); } return currentMousePoint; } private void MouseEvent(MouseEvents value) { MousePoint position = GetCursorPosition(); mouse_event ((int)value, position.X, position.Y, 0, 0) ; }
So after managing to compile the dll with COM support, with much reading of this forum and many posts fromĀ paulpmeier,Ā ptrex,Ā LarsJ, and others about loading .net, I managed to get this all working.
Here is the BotIt Core:
; BotIt Core Global $sPath = "BotIt.dll" Global $RegAsmPath = "C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe" Func BotIt_StartUp() RegisterBotIt() OnAutoItExitRegister("UnregisterBotIt") EndFunc ;==>BotIt_StartUp Func RegisterBotIt() RunWait($RegAsmPath & " /register /codebase /tlb " & $sPath, @ScriptDir, @SW_HIDE) EndFunc ;==>RegisterBotIt Func UnregisterBotIt() FileDelete("Step.txt") RunWait($RegAsmPath & " /unregister " & $sPath, @ScriptDir, @SW_HIDE) EndFunc ;==>UnregisterBotIt Func ActivateAndSearch($sTitle, $sImgPath, $bClick = True) WinActivate($sTitle) Sleep(1000) $oBotIt = ObjCreate("BotIt.DetectImageAndClick") ConsoleWrite($sImgPath & @CRLF & $bClick & @CRLF) $bRet = $oBotIt.FindAndClick($sImgPath, $bClick) Return $bRet EndFunc ;==>ActivateAndSearch Ā
Usage:
Do Sleep(500) Until ActivateAndSearch("Window Title", "PathToFile")
I hope you enjoy!
Regards,
ScrapeYourself
Ā
Ā
BotIt.cs
-
By ptrex
WHAT : is .NET Common Language Runtime (CLR) Framework
The Common Language Runtime (CLR) is a an Execution Environment . Common Language Runtime (CLR)'s main tasks are to convert the .NET Managed Code to native code, manage running code like a Virtual Machine, and also controls the interaction with the Operating System.
As part of Microsoft's .NET Framework, the Common Language Runtime (CLR) is managing the execution of programs written in any of several supported languages.Ā Allowing them to share common object-oriented classes written in any of the languages.
HOW :Ā To access the CLR environment you need toĀ create an Appdomain Object - _CLR_GetDefaultDomain()
AnĀ AppDomain provides an isolated region in which code runs inside of an existing process.
Application domains provide an isolation boundary for security, reliability, and versioning, and for unloading assemblies. Application domains are typically created by runtime hosts, which are responsible for bootstrapping the common language runtime before an application is run.
WHEN : Would you use CLR Runtime Hosts
Ā 1. To access Ā .NET Class Libraries :
System System.Collections System.Data System.Drawing System.IO System.Text System.Threading System.Timers System.Web System.Web.Services System.Windows.Forms System.Xml Ā 2. Accessing custom build .Net AssembliesĀ :
Ā Some Examples (but there are a ton out there)
AutoItX3Ā - The .NET Assembly for using AutoItX JSonToXML libr. XMLRPC Libr. .NETPDF libr. .NETOCR Libr WInSCP Libr. Ā ... Ā 3. To Compile .Net Code into an Assembly
Ā 4. To Run C# or VB.net Code
Ā 5. To Mix AU3Ā and .Net functionality in your Application
Ā
WHERE : Ā To find documentation about CLR
First of all you can find a lot on MSDN and here Ā :Ā Post 4 & Post 6
Ā
EXAMPLES : Multiple examples included in Zip !!
Example : āSystem.Text.UTF8Encodingā
Example : āSystem.IO.FileInfoā
Example : āSystem.Windows.Formsā
Example : AutoItX3Ā Custom .NET AssemblyĀ AutoItX
Example : Compile Code C# and Code VB
Example : Compile Code C# at Runtime
Ā
WHO : Created the CLR.au3 UDF
All credits go to : Danyfirex / Larsj / TrancexxĀ / Junkew
Ā
TO DO :Ā The library is still Work in Process ā¦
(Some of the GUI Controls are not yet working as expected...)
Anyone isĀ free to participate in contributing to get the bugs resolved and to expand the CLR.au3 functionality ...
Enjoy !!
DOWNLOADSĀ :Ā (Last updated)Ā
- added CLR Constants.au3Ā - Danyfirex
Ā Ā Ā - Global Constants added (Magic numbers)
- added .NET CLR CreateObject vs ObjCreate Example.au3 - Junkew
     ⢠2 approaches give the same result (only valid for COM Visible Assembly)
     ⢠Includes a function that shows you which Assembly Classes are COM Visible
- added .Net Conventional COM Objects Examples - ptrex
- added .NET CLR CreateComInstanceFrom Example - Danyfirex
Ā Ā Ā - You can use it for Regfree COM Assembly Access
Ā Ā Ā - System.Activator has 4 methods :
      ⢠CreateComInstanceFrom : Used to create instances of COM objects.
      ⢠CreateInstanceFrom : Used to create a reference to an object from a particular assembly and type name.
      ⢠GetObject : Used when marshaling objects.
      ⢠CreateInstance : Used to create local or remote instances of an object.
- added .NET Access SafeArrays Using AccVarsUtilities Example - LarsJ
- added SafeArray Utilities functions in Includes - LarsJĀ
- added .NET Access Native MSCorLib Classes - System - ptrex
Ā Ā Multiple System Class Examples :
     ⢠System.Random
     ⢠ System.DateTime
     ⢠ System.Diagnostics.PerformanceCounter
     ⢠ System.IO.FileInfo
     ⢠ System.Int32
     ⢠ System.Double
     ⢠ System.Speech
     ⢠System.Web
- added Third Party Assembly Access - ptrex
     ⢠WinSCP : https://winscp.net/eng/download.php
     ⢠IonicZip : http://dotnetzip.codeplex.com/
- added more Examples using PowerShell GUIĀ Assembly Access - ptrexĀ
Ā Ā Ā Ā Ā ā¢Ā GUI Ribbon .NET Assembly using CLR LibraryĀ
Ā Ā Ā Ā Ā ā¢Ā GUI Report Designer .NET Assembly using CLR Library
     ⢠ GUI SSRS Reporting .NET Assembly using CLR Library
Ā
CLRv3a.zip
.NET CLR Framework for AutoIT.pdf
-
By Bilgus
Trying to figure out how to do CallByName on AutoIt COMĀ objects due to the lack of being able to set properties within an Execute() statement
Several Ideas were TriedĀ https://www.autoitscript.com/forum/topic/200129-set-object-properties-with-propertyname-and-value-taken-from-an-array/
I think this is the best; Patching the vtable of IDispatch so we can intercept a Fake function call ($obj.Au3_CallByName)
use it like this
Local $oDictionary = ObjCreate("Scripting.Dictionary") ; EXAMPLE Au3_CallByname_Init() ; (you can optionally provide a classname here but we patch the main Idispatch interface so really no need) $Au3_CallByName = "Add" ; Method we want to call $oDictionary.Au3_CallByName("Test", "Value") Au3_CallByname_Init(False) ; (Not Strictly Needed unhooked on exit) NOTE:Ā Ā Au3_CallByname_Init() doesn't have to be called at the top of the script, just call it before you need to call by name...
Code + Example
#Region ;**** Directives created by AutoIt3Wrapper_GUI **** #AutoIt3Wrapper_UseX64=y #AutoIt3Wrapper_AU3Check_Parameters=-d -w 1 -w 2 -w 3 -w- 4 -w 5 -w 6 #EndRegion ;**** Directives created by AutoIt3Wrapper_GUI **** ;Au3CallByName, Bilgus Global $Au3_CallByName = 0 Local $hKernel32 = DllOpen("Kernel32.dll") OnAutoItExitRegister(__CallByNameCleanup) Func __CallByNameCleanup() Au3_CallByName_Init(False) ;Unload DllClose($hKernel32) EndFunc ;==>__CallByNameCleanup ; Takes a pointer to the v-table in a class and replaces specified member Id in it to a new one. Func __HookVTableEntry($pVtable, $iVtableOffset, $pHook, ByRef $pOldRet) ;;https://www.autoitscript.com/forum/topic/107678-hooking-into-the-idispatch-interface/ Local Const $PAGE_READWRITE = 0x04 Local $tpVtable = DllStructCreate("ptr", $pVtable) Local $szPtr = DllStructGetSize($tpVtable) Local $pFirstEntry, $pEntry, $tEntry, $aCall, $flOldProtect, $bStatus ; Dereference the vtable pointer $pFirstEntry = DllStructGetData($tpVtable, 1) $pEntry = $pFirstEntry + ($iVtableOffset * $szPtr) ; Make the memory free for all. Yay! $aCall = DllCall($hKernel32, "int", "VirtualProtect", "ptr", $pEntry, "long", $szPtr, "dword", $PAGE_READWRITE, "dword*", 0) If @error Or Not $aCall[0] Then ConsoleWriteError("Error: Failed To hook vTable" & @CRLF) Return False EndIf $flOldProtect = $aCall[4] $tEntry = DllStructCreate("ptr", $pEntry) $pOldRet = DllStructGetData($tEntry, 1) If $pOldRet <> $pHook Then DllStructSetData($tEntry, 1, $pHook) $bStatus = True Else ;Already Hooked ConsoleWriteError("Error: vTable is already hooked" & @CRLF) $bStatus = False EndIf ;put the memory protect back how we found it DllCall($hKernel32, "int", "VirtualProtect", "ptr", $pEntry, "long", $szPtr, "dword", $flOldProtect, "dword*", 0) Return $bStatus EndFunc ;==>__HookVTableEntry ; Everytime autoit wants to call a method, get or set a property in a object it needs to go to ; IDispatch::GetIDsFromNames. This is our version of that function, note that by defining this ourselves ; we can fool autoit to believe that the object supports a lot of different properties/methods. Func __IDispatch_GetIDsFromNames($pSelf, $riid, $rgszNames, $cNames, $lcid, $rgDispId) Local Const $CSTR_EQUAL = 0x02 Local Const $LOCALE_SYSTEM_DEFAULT = 0x800 Local Const $DISP_E_UNKNOWNNAME = 0x80020006 Local Static $pGIFN = __Pointer_GetIDsFromNames() Local Static $tpMember = DllStructCreate("ptr") If $Au3_CallByName Then Local $hRes, $aCall, $tMember ;autoit only asks for one member $aCall = DllCall($hKernel32, 'int', 'CompareStringW', 'dword', $LOCALE_SYSTEM_DEFAULT, 'dword', 0, 'wstr', "Au3_CallByName", 'int', -1, _ 'struct*', DllStructGetData(DllStructCreate("ptr[" & $cNames & "]", $rgszNames), 1, 1), 'int', -1) If Not @error And $aCall[0] = $CSTR_EQUAL Then ;ConsoleWrite("CallByName: " & $Au3_CallByName & @CRLF) $tMember = DllStructCreate("wchar[" & StringLen($Au3_CallByName) + 1 & "]") DllStructSetData($tMember, 1, $Au3_CallByName) DllStructSetData($tpMember, 1, DllStructGetPtr($tMember)) $rgszNames = $tpMember $Au3_CallByName = 0 EndIf EndIf ;Call the original GetIDsFromNames $hRes = DllCallAddress("LRESULT", $pGIFN, "ptr", $pSelf, "ptr", $riid, _ "struct*", $rgszNames, "dword", $cNames, "dword", $lcid, "ptr", $rgDispId) If @error Then ConsoleWrite("Error: GetIDsFromNames: " & @error & @CRLF) Return $DISP_E_UNKNOWNNAME EndIf Return $hRes[0] EndFunc ;==>__IDispatch_GetIDsFromNames Func __Pointer_GetIDsFromNames($ptr = 0) Local Static $pOldGIFN = $ptr If $ptr <> 0 Then $pOldGIFN = $ptr Return $pOldGIFN EndFunc ;==>__Pointer_GetIDsFromNames Func Au3_CallByName_Init($bHook = True, $classname = "shell.application") Local Const $iOffset_GetIDsFromNames = 5 Local Static $IDispatch_GetIDsFromNames_Callback = 0 Local $oObject, $pObject, $pHook, $pOldGIFN If $bHook Then If $IDispatch_GetIDsFromNames_Callback = 0 Then $IDispatch_GetIDsFromNames_Callback = DllCallbackRegister("__IDispatch_GetIDsFromNames", "LRESULT", "ptr;ptr;ptr;dword;dword;ptr") EndIf $pHook = DllCallbackGetPtr($IDispatch_GetIDsFromNames_Callback) Else $pHook = __Pointer_GetIDsFromNames() If $pHook <= 0 Then Return ;Already Unloaded EndIf $oObject = ObjCreate($classname) $pObject = DllStructSetData(DllStructCreate("ptr"), 1, $oObject) If __HookVTableEntry($pObject, $iOffset_GetIDsFromNames, $pHook, $pOldGIFN) Then __Pointer_GetIDsFromNames($pOldGIFN) ;Save the original pointer to GetIDsFromNames If Not $bHook Then DllCallbackFree($IDispatch_GetIDsFromNames_Callback) $IDispatch_GetIDsFromNames_Callback = 0 EndIf Else ;Error EndIf $oObject = 0 EndFunc ;==>Au3_CallByName_Init ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;TESTS; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Au3_CallByName_Init() #include <ie.au3> Global $oRegistrationInfo = _IECreate() Global $aRegistrationInfo[] = ['Left=10', 'Top= 10', 'Width=450', 'Height=600'] Global $oObject = $oRegistrationInfo Local $oDictionary = ObjCreate("Scripting.Dictionary") Local $oDictionary2 = ObjCreate("Scripting.Dictionary") ;Au3_CallByName_Init($oObject) __TS_TaskPropertiesSet($oObject, $aRegistrationInfo) MsgBox(0, "Info", "Press OK to exit") $oRegistrationInfo.quit $oRegistrationInfo = 0 $oObject = 0 Sleep(1000) For $i = 1 To 10 $Au3_CallByName = "Add" $oDictionary.Au3_CallByName("test1:" & $i, "Dictionary Item: " & $i) Next $Au3_CallByName = "keys" For $sKey In $oDictionary.Au3_CallByName() For $j = 0 To 1 $Au3_CallByName = ($j = 0) ? "Item" : "Exists" ConsoleWrite($sKey & " -> " & $oDictionary.Au3_CallByName($sKey) & @CRLF) Next Next Au3_CallByName_Init(False) ;Unload Au3_CallByName_Init() Local $aRegistrationInfo[] = ['Left=1000', 'Width=450'] ConsoleWrite(@CRLF & "NEW IE" & @CRLF & @CRLF) $oRegistrationInfo = _IECreate() __TS_TaskPropertiesSet($oRegistrationInfo, $aRegistrationInfo) MsgBox(0, "Info", "Press OK to exit") $oRegistrationInfo.quit For $i = 1 To 10 $Au3_CallByName = "Add" $oDictionary2.Au3_CallByName("test2:" & $i, "Dictionary Item: " & $i) Next $Au3_CallByName = "keys" For $sKey In $oDictionary2.Au3_CallByName() For $j = 0 To 1 $Au3_CallByName = ($j = 0) ? "Item" : "Exists" ConsoleWrite($sKey & " -> " & $oDictionary2.Au3_CallByName($sKey) & @CRLF) Next Next Au3_CallByName_Init(False) ;Unload (Not Strictly Needed, Done on Script Close) Func __TS_TaskPropertiesSet(ByRef $oObject, $aProperties) Local $aTemp If IsArray($aProperties) Then For $i = 0 To UBound($aProperties) - 1 $aTemp = StringSplit($aProperties[$i], "=", 2) ; 2 -> $STR_NOCOUNT) If @error Then ContinueLoop ConsoleWrite("Command: $oObject." & $aTemp[0] & " = " & $aTemp[1] & @CRLF) $Au3_CallByName = $aTemp[0] $oObject.Au3_CallByName = $aTemp[1] ConsoleWrite("Result : " & Hex(@error) & @CRLF) ; If @error Then Return SetError(1, @error, 0) Next EndIf EndFunc ;==>__TS_TaskPropertiesSet Ā
-