# create assembly in AuotIT

## Recommended Posts

Is there anyway to create an assembly for AutoIT so that I can use that in Powershell or Dotnet supported languages like c#.

Like I want to use the functionality of _ArrayDisplay of AutoIT in C# by creating a assmbly/library and using that in the target language.

##### Share on other sites

Not sure what you want but this comes close

But then you start in AutoIt

##### Share on other sites

How to create a library in AutoIT so that we can use this dll or library in other programming languages.

##### Share on other sites

It is not possible to create a Dynamic Link Library since AutoIt is interpreted, not compiled to machine code

##### Share on other sites

If you want to use AutoIt in C#/.NET you can at least use this:

UHJvZmVzc2lvbmFsIENvbXB1dGVyZXI=

##### Share on other sites

With CLR.AU3 as given earlier there is an example: .NET GUI Form Controls & Events 2.au3 that shows how to catch events sent from the C# class

So the approach could be

1.  Build an exe with AutoIt which hosts the clr (by using clr.au3) and has the needed udf's of AutoIt in it

2. The C# assembly that is loaded by step 1 communicates with c# assembly / exe from step 3

3. The C# exe you made yourself

So although its not a dll created in step 1 in step 3 you could also start the exe of step 1 that was build with AutoIt3.

Its an area nobody has been investigating but with WCF https://msdn.microsoft.com/en-us/library/ms731184.aspx

@Danyfirex is in this area the most knowledgable person I feel. Maybe he can add his thought on this.

##### Share on other sites

I'm really no interested in this kind of stuff.  ( But maybe I read later)

I would prefer don't spend so much time doing that. You probably want to do  something easier to avoid a lot of variable type casting.

Some suggestions.

1. Build your _arrayDisplay In each lenguage you want to use (I think would no be hard using PowerShell r C#)

2. Create a Commandline tool where you can pass maybe a file path with your data written from your PS or C# app and parse/show with arraydisplay.

Saludos

AutoIt...

##### Share on other sites

With AutoIt object I remember they registered to the running object table and as such AutoIt could act as a com server.

I would classify that in the area advanced++ topics and probably not the right solution to your problem

##### Share on other sites

Here is some simple code for a start. You can find it all in the zip below.

Run CSharpArrayDisplay.au3 or CSharpArrayDisplayEx.au3 from SciTE.

;#AutoIt3Wrapper_UseX64=y

#include <Array.au3>
#include <WinAPI.au3>
#include <WinAPIDlg.au3>

#include "Includes\CLR.au3"

ArrayDisplay()

Func ArrayDisplay()
Local $sFile = _WinAPI_OpenFileDlg( "Open C# source file", @WorkingDir, "C# source file (*.cs)", 1, "", "", BitOR($OFN_PATHMUSTEXIST, $OFN_FILEMUSTEXIST,$OFN_HIDEREADONLY ) )
If @error Then Return ConsoleWrite( "Open file ERR" & @CRLF )
ConsoleWrite( "Open file OK" & @CRLF )

; Get .NET Dll-references
Local $aSrcArray,$aSplit, $sReferences = "System.dll"$aSrcArray = FileReadToArray( $sFile ) For$i = 0 To UBound( $aSrcArray ) - 1 If StringInStr($aSrcArray[$i], "using " ) = 1 Then$aSplit = StringSplit( $aSrcArray[$i], "using ", 3 ) ; 3 =  $STR_ENTIRESPLIT +$STR_NOCOUNT
$aSplit = StringSplit($aSplit[1], ";", 2 )
$aSplit[0] = StringStripWS($aSplit[0], 7 ) ; 7 = $STR_STRIPLEADING +$STR_STRIPTRAILING + $STR_STRIPSPACES If$aSplit[0] = "System" Then ContinueLoop
$sReferences &= " | " &$aSplit[0] & ".dll"
ElseIf $aSrcArray[$i] = "class ArrayDisplayClass" Then
ExitLoop
EndIf
Next
If $i = UBound($aSrcArray ) Then Return ConsoleWrite( "ArrayDisplayClass ERR" & @CRLF )
ConsoleWrite( "ArrayDisplayClass OK" & @CRLF )

Local $oAssembly,$oArrayDisplayClass, $aArray$oAssembly = _CLR_CompileCSharp( FileRead( $sFile ),$sReferences )
If Not IsObj( $oAssembly ) Then Return ConsoleWrite( "$oAssembly ERR" & @CRLF )
ConsoleWrite( "$oAssembly OK" & @CRLF )$oAssembly.CreateInstance( "ArrayDisplayClass", $oArrayDisplayClass ) If Not IsObj($oArrayDisplayClass ) Then Return ConsoleWrite( "$oArrayDisplayClass ERR" & @CRLF ) ConsoleWrite( "$oArrayDisplayClass OK" & @CRLF )

$aArray =$oArrayDisplayClass.ArrayDisplay()
_ArrayDisplay( $aArray, "", "", 8 ) EndFunc This is your own original C# code where you want to display an array. Note that the original source file is the a-version. Eg. IntArray-a.cs: using System; class MyClass { public void MyMethod() { int[] MyArray = new [] { 1, 2, 3 }; } } To display the array with _ArrayDisplay or _ArrayDisplayEx you have to add a few lines of code to the original source. Here the code is added to IntArray.cs: using System; class ArrayDisplayClass { public int[] array; public int[] ArrayDisplay() { MyMethod(); return array; } public void MyMethod() { int[] MyArray = new [] { 1, 2, 3 }; array = MyArray; } } You can find a handful of examples in the zip file. Edited by LarsJ ##### Link to post ##### Share on other sites • 3 weeks later... And as wonderfull reference LarsJ gave ##### Link to post ##### Share on other sites ## Create an account or sign in to comment You need to be a member in order to leave a comment ## Create an account Sign up for a new account in our community. It's easy! Register a new account ## Sign in Already have an account? Sign in here. Sign In Now • ### Recently Browsing 0 members No registered users viewing this page. • ### Similar Content • Hi all, My programming knowledge is very basic. I have an old script that creates shares and assign permissions. It normally registers SetAcl.ocx if necessary and creates an object to assign permissions. The command that registers SetAcl was apparently working fine under Windows 7 but is not working under Windows 10. RunWait("regsvr32.exe path\to\setacl.ocx /s", "", @SW_HIDE) As I'm logged in as admin, I changed this command to : RunAsWait(@UserName, "", "", 0, "regsvr32.exe path\to\setacl.ocx /s", "", @SW_HIDE) It seems to terminate correctly but the script still doesn't work as expected. To check that, I've created that small script : Local$objSetAcl = ObjCreate("SETACL.SetACLCtrl.1") If IsObj($objSetAcl) Then ConsoleWrite("Object successfully created." & @CRLF) Else ConsoleWrite("Object not created. Registering SetAcl.ocx" & @CRLF) Local$result = RunAsWait(@UserName, "", "", 0, "regsvr32.exe path\to\setacl.ocx /s", "", @SW_HIDE); Use of my admin username to elevate CMD ConsoleWrite("Return code : " & $result & @CRLF) ConsoleWrite("Creating object" & @CRLF)$objSetAcl = ObjCreate("SETACL.SetACLCtrl.1") If IsObj($objSetAcl) Then ConsoleWrite("Object successfully created." & @CRLF) Else ConsoleWrite("Object creation failed." & @CRLF) EndIf EndIf It tries to register SetAcl.ocx, return code 0 seems to be fine but still can't use SetAcl. But if I go to CMD as admin, run the regsvr32 command and restart my script, it can create the object without issue. I know my poor knowledge makes me miss something. Anyone can help me figure this out ? • By Celtic88 hello ! just for fun simple code to call dll api in new thread ... *update 21/02/2021 -add callback for return api call -add x64 ;by celtic 88 #include <Memory.au3> #include <WinAPISys.au3> #include <WinAPIProc.au3> #include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #include <WinAPIEx.au3> #include <WindowsConstants.au3> #include <WinAPIMem.au3> Global$thread_Class = 'thread_Class1' Local $hProc = DllCallbackRegister('thread_WM', 'lresult', 'hwnd;uint;wparam;lparam') Local$tClass = DllStructCreate('wchar[' & StringLen($thread_Class) + 1 & ']') DllStructSetData($tClass, 1, $thread_Class) Local$tWCEX = DllStructCreate($tagWNDCLASSEX) DllStructSetData($tWCEX, 'Size', DllStructGetSize($tWCEX)) DllStructSetData($tWCEX, 'hWndProc', DllCallbackGetPtr($hProc)) DllStructSetData($tWCEX, 'ClassName', DllStructGetPtr($tClass)) _WinAPI_RegisterClassEx($tWCEX) Global $opcode_struct = 'ptr WaitForSingleObject;' & _ 'ptr SendMessage;' & _ 'ptr GetLastError;' & _ 'ptr henvent;' & _ 'ptr hwnd;' & _ 'ptr pproc;' & _ 'ptr isprocessing;' & _ 'ptr lreturn;ptr hreturn;' & _ 'ptr LastError;' & _ 'ptr exitthread;' & _ 'ptr parm[100];ptr rsv[20];WCHAR callback[100]' Local$opcode = '0x668CC83C337449' & _ '8B7C24046AFFFF770CFF1785C07403FF47288B5F2885DB75118D772C8B0E85C97405FF348EE2FBFF571489471C895720FF570889472431C0894718535750FF7710FF570485DB74BCC3' & _ '4881EC480300004889CB4831D248FFCA488B4B18FF134885C0740448FF43504C8B7B504D85FF753A488D735848AD4885C0742C4989C64831C94883C10448AD50E2FB4983EE04493' & _ '9CE7E0E4C89F1488D7C244048AD48ABE2FA415941585A59FF53284889433848895340FF5310488943484831D2488953304D89F94989D8488B4B20FF53084D85FF74804881C448030000C3' Global $pshll = _MemVirtualAlloc(0, BinaryLen($opcode), $MEM_COMMIT,$PAGE_EXECUTE_READWRITE) DllStructSetData(DllStructCreate('byte[' & BinaryLen($opcode) & ']',$pshll), 1, $opcode) Func thread_WM($hWnd, $iMsg,$wParam, $lParam) ;window call back If$iMsg = $WM_NULL Then Local$thi = DllStructCreate($opcode_struct,$wParam) If $lParam <> 0 Then DllStructSetData($thi, 'rsv', -2, 4) DllStructSetData($thi, 'rsv', DllStructGetData($thi, 'rsv', 4) + 1, 4) Call(DllStructGetData($thi, 'callback'),$thi, DllStructGetData($thi, 'rsv', 4)) If$lParam <> 0 Then _WinAPI_DestroyWindow($hWnd) _WinAPI_CloseHandle(DllStructGetData($thi, 'henvent')) _MemGlobalFree($wParam) EndIf EndIf Return _WinAPI_DefWindowProc($hWnd, $iMsg,$wParam, $lParam) EndFunc ;==>thread_WM Func thread_create($scallback) ; create new remote api thread Local $thi = DllStructCreate($opcode_struct, _MemGlobalAlloc(DllStructGetSize(DllStructCreate($opcode_struct)),$GPTR)) DllStructSetData($thi, 'WaitForSingleObject', _WinAPI_GetProcAddress(_WinAPI_LoadLibrary('kernel32'), 'WaitForSingleObject')) DllStructSetData($thi, 'SendMessage', _WinAPI_GetProcAddress(_WinAPI_LoadLibrary('user32'), 'SendMessageW')) DllStructSetData($thi, 'GetLastError', _WinAPI_GetProcAddress(_WinAPI_LoadLibrary('kernel32'), 'GetLastError')) DllStructSetData($thi, 'henvent', _WinAPI_CreateEvent(0, 0, 0, 0)) ; DllStructSetData($thi, 'hwnd', _WinAPI_CreateWindowEx(0,$thread_Class, '', 0, 0, 0, 0, 0, 0)) Local $thid = DllCall('kernel32', 'hwnd', 'CreateThread', 'ptr', 0, 'dword', 0, 'ptr', _$pshll, 'ptr', DllStructGetPtr($thi), 'long', 0, 'int*', 0) DllStructSetData($thi, 'rsv', $thid[0], 2) DllStructSetData($thi, 'rsv', $thid[6], 3) DllStructSetData($thi, 'callback', $scallback) Call(DllStructGetData($thi, 'callback'), $thi, DllStructGetData($thi, 'rsv', 4)) Return $thi EndFunc ;==>thread_create Func thread_close($thi) ; close remote api thread DllStructSetData($thi, 'exitthread', 1) _WinAPI_SetEvent(DllStructGetData($thi, 'henvent')) EndFunc ;==>thread_close Func thread_isrunning($thi) ; check if remote api thread is closed or no Return (DllStructGetData($thi, 'exitthread') = 0) EndFunc ;==>thread_isrunning Func thread_GetLastError($thi) ; Get Last Error in remote thread Return DllStructGetData($thi, 'LastError') EndFunc ;==>thread_GetLastError Func thread_getreturn($thi) ; get api call return Return DllStructGetData($thi, 'lreturn') EndFunc ;==>thread_getreturn Func thread_call($thi,$pproc) ; dllcall $pproc = address of api DllStructSetData($thi, 'pproc', $pproc) DllStructSetData($thi, 'isprocessing', 1) _WinAPI_SetEvent(DllStructGetData($thi, 'henvent')) DllStructSetData($thi, 'rsv', 0, 1) EndFunc ;==>thread_call Func thread_addcallparameters($thi,$val) ; add dllcall parameters Local $idx = DllStructGetData($thi, 'rsv', 1) + 1 DllStructSetData($thi, 'rsv',$idx, 1) DllStructSetData($thi, 'parm',$idx, 1) DllStructSetData($thi, 'parm',$val, $idx + 1) EndFunc ;==>thread_addcallparameters Func thread_callsimple($thi, $dll,$nproc, $p1 = Default,$p2 = Default, $p3 = Default, _$p4 = Default, $p5 = Default,$p6 = Default, $p7 = Default,$p8 = Default, _ $p9 = Default,$p10 = Default, $p11 = Default,$p12 = Default, $p13 = Default, _$p14 = Default, $p15 = Default,$p16 = Default, $p17 = Default,$p18 = Default) ; simple call api ;) Local $cp = 1 While Execute('$p' & $cp & ' <> Default') thread_addcallparameters($thi, Execute('$p' &$cp)) $cp += 1 WEnd thread_call($thi, _WinAPI_GetProcAddress(_WinAPI_LoadLibrary($dll),$nproc)) EndFunc ;==>thread_callsimple Opt("MustDeclareVars", 1) Global $s1,$s2 Func __thread_callback($thi,$phase) Switch $phase Case -1 ;thread is closed MsgBox(0, '', 'thread is closed return ' & thread_getreturn($thi) & ' error ' & thread_GetLastError($thi)) Case 0 ;thread is started$s1 = _WinAPI_CreateString('i love autoit') $s2 = _WinAPI_CreateString('from remote thread') thread_callsimple($thi, 'user32', 'MessageBoxW', 0, $s1,$s2, 0x00000006) ;~ ;DllCall('user32', 'int', 'MessageBoxW', 'hwnd', 0, 'ptr', $s1, 'ptr',$s2, 'uint', 0x00000006) Case 1 ;return first call _WinAPI_FreeMemory($s1) _WinAPI_FreeMemory($s2) MsgBox(0, '', 'callback api return ' & thread_getreturn($thi) & ' error ' & thread_GetLastError($thi)) $s2 = DllStructCreate('dword') DllStructSetData($s2, 1, 1024) $s1 = DllStructCreate('wchar[1024]') thread_callsimple($thi, 'Advapi32', 'GetUserNameW', DllStructGetPtr($s1), DllStructGetPtr($s2)) ;~ ;DllCall('Advapi32', 'BOOL', 'GetUserNameW', 'ptr', DllStructGetPtr($s1), 'ptr', DllStructGetPtr($s2)) Case 2 ;return second call MsgBox(0, '', 'callback api return : ' & thread_getreturn($thi) & _ @CRLF & ' error : ' & thread_GetLastError($thi) & _ @CRLF & ' string len : ' & DllStructGetData($s2, 1) & _ @CRLF & ' user name : ' & DllStructGetData($s1, 1) & _ '') thread_close($thi) ;endif thread Case 3 ; return previous call EndSwitch EndFunc ;==>__thread_callback Local$rth = thread_create('__thread_callback') While thread_isrunning(rth) ConsoleWrite('thread is running' & @CRLF) Sleep(1000) WEnd • Dear members of the forum, I'm working on a project in which I have to use Image recognition technique. Due to client restrictions, I couldn't use AutoIt for this project. Is there a way to use this DLL "ImageSearchDLL.dll" (which is used to do image recognition steps in AutoIt) in VB.Net to achieve the same result? I have used this DLL few years before and got good results. If there is a latest version of this DLL and if you can share it, that will be helpful too. Any guidance is deeply appreciated. • By Beege Here is the latest assembly engine from Tomasz Grysztar, flat assembler g as a dll which I compiled using original fasm engine. He doesn't have it compiled in the download package but it was as easy as compiling a exe in autoit if you ever have to do it yourself. Just open up the file in the fasm editor and press F5. You can read about what makes fasmg different from the original fasm HERE if you want . The minimum you should understand is that this engine is bare bones by itself not capable of very much. The macro engine is the major difference and it uses macros for basically everything now including implementing the x86 instructions and formats. All of these macros are located within the include folder and you should keep that in its original form. When I first got the dll compiled I couldn't get it to generate code in flat binary format. It was working but size of output was over 300 bytes no matter what the assembly code and could just tell it was outputting a different format than binary. Eventually I figured out that within the primary "include\win32ax.inc"', it executes a macro "format PE GUI 4.0" if x86 has not been defined. I underlined macro there because at first I (wasted shit loads of time because I) didn't realize it was a macro (adding a bunch of other includes) since in version 1 the statement "format binary" was a default if not specified and specifically means add nothing extra to the code. So long story short, the part that I was missing is including the cpu type and extensions from include\cpu folder. By default I add x64 type and SSE4 ext includes. Note that the x64 here is not about what mode we are running in, this is for what instructions your cpu supports. if you are running on some really old hardware that may need to be adjusted or if your on to more advanced instructions like the avx extensions, you may have to add those includes to your source. Differences from previous dll function I like the error reporting much better in this one. With the last one we had a ton error codes and a variable return structure depending on what kind of error it had. I even had an example showing you what kind of an error would give you correct line numbers vs wouldn't. With this one the stdout is passed to the dll function and it simply prints the line/details it had a problem with to the console. The return value is the number of errors counted. It also handles its own memory needs automatically now . If the output region is not big enough it will virtualalloc a new one and virtualfree the previous. Differences in Code Earlier this year I showed some examples of how to use the macros to make writing assembly a little more familiar. Almost all the same functionality exists here but there are a couple syntax sugar items gone and slight change in other areas. Whats gone is FIX and PTR. Both syntax sugar that dont really matter. A couple changes to structures as well but these are for the better. One is unnamed elements are allowed now, but if it does not have a name, you are not allowed to initialize those elements during creation because they can only be intialized via syntax name:value . Previously when you initialized the elements, you would do by specifying values in a comma seperated list using the specific order like value1,value2,etc, but this had a problem because it expected commas even when the elements were just padding for alignment so this works out better having to specify the name and no need for _FasmFixInit function. "<" and ">" are not longer used in the initializes ether. OLD:sTag = 'byte x;short y;char sNote[13];long odd[5];word w;dword p;char ext[3];word finish' _(_FasmAu3StructDef('AU3TEST', $sTag));convert and add definition to source _(' tTest AU3TEST ' & _FasmFixInit('1,222,<"AutoItFASM",0>,<41,43,43,44,45>,6,7,"au3",12345',$sTag));create and initalize New: $sTag = 'byte x;short y;char sNote[13];long odd[5];word w;dword p;char ext[3];word finish' _(_fasmg_Au3StructDef('AU3TEST',$sTag)) ;convert and add definition to source _(' tTest AU3TEST x:11,y:22,sNote:"AutoItFASM",odd:41,odd+4:42,odd+8:43,w:6,p:7,ext:"au3",finish:12345');create and initalize Extra Includes
I created a includeEx folder for the extra macros I wrote/found on the forums. Most of them are written by Thomaz so they may eventually end up in the standard library.
Edit: Theres only the one include folder now. All the default includes are in thier own folder within that folder and all the custom ones are top level.
Align.inc, Nop.inc, Listing.inc
The Align and Nop macros work together to align the next statement to whatever boundary you specified and it uses multibyte nop codes to fill in the space. Filling the space with nop is the default but you can also specify a fill value if you want. Align.assume is another macro part of align.inc that can be used to set tell the engine that a certain starting point is assumed to be at a certain boundary alignment and it will do its align calculations based on that value.
Listing is a macro great for seeing where and what opcodes are getting generated from each line of assembly code.  Below is an example of the source and output you would see printed to the console during the assembly. I picked this slightly longer example because it best shows use of align, nop, and then the use of listing to verify the align/nop code. Nop codes are instructions that do nothing and one use of them is to insert nop's as space fillers when you want a certian portion of your code to land on a specific boundary offset. I dont know all the best practices here with that (if you do please post!) but its a type of optimization for the cpu.  Because of its nature of doing nothing, I cant just run the code and confirm its correct because it didnt crash. I need to look at what opcodes the actual align statements made and listing made that easy.
source example:
procf and forcea macros
In my previous post I spoke about the force macro and why the need for it. I added two more macros (procf and forcea) that combine the two and also sets align.assume to the same function. As clarified in the previous post, you should only have to use these macros for the first procedure being defined (since nothing calls that procedure). And since its the first function, it should be the starting memory address which is a good place to initially set the align.assume address to.
Attached package should include everything needed and has all the previous examples I posted updated. Let me know if I missed something or you have any issues running the examples and thanks for looking

Update 04/19/2020:
A couple new macros added. I also got rid of the IncludeEx folder and just made one include folder that has the default include folder within it and all others top level.
dllstruct macro does the same thing as _fasmg_Au3StructDef(). You can use either one; they both use the macro.
getmempos macro does the delta trick I showed below using anonymous labels.
stdcallw and invokew macros will push any parameters that are raw (quoted) strings as wide characters
Ifex include file gives .if .ifelse .while .until  the ability to use stdcall/invoke/etc inline. So if you had a function called "_add" you could do .if stdcall(_add,5,5) = 10. All this basically does in the background is perform the stdcall and then replaces the comparison with eax and passes it on to the original default macros, but is super helpful for cleaning up code and took a ton of time learning the macro language to get in place.

Update 05/19/2020:
Added fastcallw that does same as stdcallw only
Corrected missing include file include\macro\if.inc within win64au3.inc
fasmg 5-19-2020.zip

Previous versions:

• Hi AutoIt Scripters/Programmers. I have a question about MIME Tools for Notepad++:
I've recently found a UDF about Base64 in forum, but they can't decode\encode correctly some emojis , other UTFs and etc. so i decided to use mimeTools.dll of Notepad++ or main site
My problem is how to use this dll in AutoIt Language?

×

• Wiki

• Back

• #### Beta

• Git
• FAQ
• Our Picks
×
• Create New...