Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 09/23/2017 in all areas

  1. .NET Common Language Runtime (CLR) Framework was published five months ago. CLR.au3 which is the main UDF makes it possible to execute .NET code directly in an AutoIt script. .NET code in this context should be perceived in a very broad sense. As shown in the examples, there are virtually no limits to the possibilities that the UDF opens up for. .NET Common Language Runtime (CLR) Framework is the result of the work in Using .NET libary with AutoIt, possible? CLR.au3 is implemented in this thread. Most of the code in CLR.au3 is a translation of CLR.ahk from .NET Framework Interop (CLR, C#, VB) in the AutoHotkey forum. DotNet.au3 is a complete translation of CLR.ahk. This example is about DotNet.au3. It contains information about the functions in the UDF. Usage of the functions is demonstrated through small examples. And there is a description of a few .NET Framework concepts. The AutoHotkey project The AutoHotkey project started in .NET Framework Interop in autumn 2009. The latest update of CLR.ahk in .NET Framework Interop (CLR, C#, VB) was november 2011. The whole project seems to have been developed over this 3-year period. The project was developed by Lexikos in the AutoHotkey forum. He certainly looks very knowledgeable about the code in the .Net Framework and he has done a great job in implementing the AutoHotkey code in CLR.ahk. Lots of credit to Lexikos. If you want to test the AutoHotkey code, you can find a recipe here. DotNet.au3 Because a lot of COM support is included internally in AutoHotkey and especially because AutoHotkey natively supports safearrays, the code in CLR.ahk is short and compact. 150 code lines. In the zip-file below AutoIt safearray support is implemented in two separate UDFs: SafeArray.au3 and AccVarsUtilities.au3. Both of these UDFs were started in Accessing AutoIt Variables. That way, it has also been possible to keep the code in DotNet.au3 short and compact. 190 code lines. You should take a look at DotNet.au3. It's nice and easily readable code (maybe not so easy to understand, but easy to read). 7 functions DotNet.au3 contains 7 functions and 2 internal functions. The first 3 functions DotNet_Start(), DotNet_StartDomain() and DotNet_StopDomain() are only used to optimize the .NET Framework host (more about .NET concepts below). If you are satisfied with the default .NET Framework host, you can completely skip these functions. The next 3 functions DotNet_LoadAssembly(), DotNet_LoadCScode() and DotNet_LoadVBcode() are used to load .NET code into a domain. Before it's possible to execute .NET code it must be loaded into a domain. If DotNet_Start() and DotNet_StartDomain() have not been called, DotNet_Start() is called automatically by the 3 functions and the default domain is used to execute .NET code. DotNet_LoadAssembly() loads .NET code in a .NET assembly DLL-file into a domain. The other functions compiles C# and VB source code on the fly, creates a .NET assembly DLL-file in memory and loads the assembly file into a domain. All 3 functions returns a .NET code object which is a reference to the .NET code. The last function DotNet_CreateObject() takes a .NET code object and a class name as input parameters and creates an object as an instance of the class. The class must be defined in the .NET code. Because .NET code is object-oriented code, everything is performed through objects. Now the methods of the object can be called and this executes the functions in the .NET code. Below is a brief description of the 7 functions. $oRuntimeHost = DotNet_Start( $sVersion = "" ) DotNet_Start() Loads the .NET Framework code-execution environment known as the CLR into the AutoIt process and returns a .NET runtime host (a .NET Framework host). Default is to use the latest version of .NET Framework installed on the PC. Specify $sVersion eg. "v2.0.50727" to use an older version of .NET Framework. DotNet_Start() is automatically called by the other functions in DotNet.au3. You only need to call DotNet_Start() if you want to use an older version of .NET Framework. @error = 1 indicates that DotNet_Start() has failed. DotNet_StartDomain( ByRef $oAppDomain, $sFriendlyName = "", $sBaseDirectory = "" ) Creates and starts a user domain to run .NET code. Several user domains can be created and started at the same time. $oAppDomain is the returned domain object. $sFriendlyName is a name to identify the domain. $sBaseDirectory is the base directory where from .NET assemblies are loaded into the domain. The only purpose of $sFriendlyName is to be able to recognize the domain when the domains are listed with DotNet_ListDomains(). DotNet_ListDomains() is a utility function implemented in DotNetUtils.au3. The purpose of $sBaseDirectory is to be able to specify the directory where .NET assemblies are stored. The usage of $sBaseDirectory is demonstrated in examples. A default domain is automatically created by the other functions in DotNet.au3. You only need to call DotNet_StartDomain() if you want to specify a base directory for the domain. DotNet_StopDomain( ByRef $oAppDomain ) Unloads .NET assemblies loaded into the user domain and stops the domain. $oAppDomain is the domain object. The default domain cannot be stopped. $oNetCode = DotNet_LoadAssembly( $sAssemblyName, $oAppDomain = 0 ) DotNet_LoadAssembly() loads .NET code in a .NET assembly DLL-file into a domain and returns a .NET code object (a reference to the .NET code). $sAssemblyName is the name of the assembly DLL-file. $oAppDomain is the user domain. If no user domain is specified the assembly is loaded into the default domain. @error = 2 indicates that DotNet_LoadAssembly() has failed. $oNetCode = DotNet_LoadCScode( $sCode, $sReferences = "", $oAppDomain = 0, $sFileName = "", $sCompilerOptions = "" ) $oNetCode = DotNet_LoadVBcode( $sCode, $sReferences = "", $oAppDomain = 0, $sFileName = "", $sCompilerOptions = "" ) DotNet_LoadCScode() and DotNet_LoadVBcode() compiles C# and VB source code on the fly, creates a .NET assembly DLL-file in memory, loads the assembly file into a domain and returns a .NET code object. $sCode is the C# or VB source code. $sReferences is a pipe (|) delimited list of .NET DLL assemblies that the C#/VB code requires. Eg. "System.dll" or "System.Windows.Forms.dll". $oAppDomain is the user domain. If no user domain is specified the code is loaded into the default domain. The other parameters are related to the compilation process. If $sFileName is the name of a DLL-file the code is compiled into a .NET assembly DLL-file. Else the code is compiled in memory. $sCompilerOptions is rarely used. See Microsoft documentation for details. @error = 3/4 indicates that DotNet_LoadCScode() or DotNet_LoadVBcode() has failed. @error = 5 indicates a syntax error in the C# or VB source code. Such an error can be corrected by correcting the error in the source code. $oObject = DotNet_CreateObject( ByRef $oNetCode, $sClassName, $v3 = Default, ..., $v9 = Default ) DotNet_CreateObject() creates an object as an instance of a class. $oNetCode is a .NET code object as returned by one of the functions DotNet_LoadAssembly(), DotNet_LoadCScode() or DotNet_LoadVBcode(). $sClassName is the name of a class defined in the .NET code. The other parameters depends on the specific class. Summary Two functions must be called to execute .NET code directly in an AutoIt script. One of the functions DotNet_LoadAssembly(), DotNet_LoadCScode() or DotNet_LoadVBcode() to load the .NET code into a domain. And DotNet_CreateObject() to create an object from a class defined in the .NET code. Now the functions in the .NET code can be executed by calling the methods of the object. .NET concepts The .NET CLR In more or less the same way as AutoIt3.exe or AutoIt3_x64.exe is needed to run AutoIt code, the .NET CLR (Common Language Runtime) or the .NET Framework code-execution environment is needed to run .NET code. To be able to run .NET code inside an AutoIt script, the CLR or the .NET Framework code-execution environment must be loaded into the AutoIt process. This is the purpose of DotNet_Start(). The CLR can be loaded into a process through several of the functions in MSCorEE.dll. CorBindToRuntimeEx is one of these functions. DotNet_Start() executes CorBindToRuntimeEx in MSCorEE.dll and loads the CLR into the AutoIt process. A program or a part of a program which is able to start the CLR and execute .NET code is referred to as a .NET runtime host, a CLR host or simply a .NET Framework host. The code in DotNet.au3 implements an AutoIt .NET Framework host. Managed/unmanaged code .NET code which is executed (or managed) through the functions in the CLR is referred to as managed code. C# and VB code is managed code. Code which is not executed through the functions in the CLR is referred to as unmanaged code. AutoIt code is unmanaged code. You usually only distinguish between managed/unmanaged code in relation to .NET code and the .NET Framework. When you are executing .NET code there is often a part of both unmanaged and managed code involved. If you are executing .NET code through AutoIt, the AutoIt code is the unmanaged code and the .NET code is the managed code. The functions in MSCorEE.dll are some of the functions which belongs to the .NET Framework that can be executed from unmanaged code eg. AutoIt code. That's the reason why these functions are used to start the .NET Framework. The COM interfaces _AppDomain, _Assembly and _Type in Interfaces.au3 are some of the interfaces which belongs to the .NET Framework that can be used in unmanaged code. That's the reason why these interfaces are used to implement the functions in DotNet.au3. Managed code like C# cannot be translated into unmanaged code like AutoIt. There is no way to translate a command like "using System;" from C# to AutoIt. In many situations you can implement the same code in AutoIt as you can in C#. But that's generally not a simple translation of the C# code. It's a new implementation of the code. .NET domains With the functions in DotNet.au3 you can create an AutoIt .NET Framework host as shown in this picture: The blue box illustrates the unmanaged AutoIt code which is used to start the .NET Framework and load the CLR into the AutoIt process. The red box illustrates the default domain and several user domains where the managed .NET code is executed. Managed .NET code is always executed within a domain. The purpose of DotNet_StartDomain() and DotNet_StopDomain() is to create, start and stop user domains. If DotNet_StartDomain() isn't called the default domain is used. A domain in managed code is equivalent to a process in unmanaged code. The purpose of domains is to prevent that a crash in one part of the .NET code should lead to a crash in all of the .NET code. A crash of the code in a domain makes the domain inapplicable and a new domain must be created with DotNet_StartDomain(). This is very similar to the way that code is executed in separate processes in the operating system. The purpose of executing code in separate processes is (among other things) to prevent that a crash of the code in one process should lead to a crash of the code in several processes and finally to a crash of the entire operating system. A crash of the code in the default domain makes the entire CLR, that's loaded into the AutoIt process inapplicable. Because it's only possible to load the CLR into the same process once, the only way to reload the CLR is to restart the entire AutoIt process. That is to stop and start the AutoIt script. Usually it does not matter if the default domain or a user domain is used to execute .NET code. It's only strictly necessary to create a user domain if there is a need to specify a base directory for .NET assemblies. The only way to specify a base directory is through DotNet_StartDomain(). .NET assemblies Before it's possible to execute .NET code in a domain, the code must be loaded into the domain. Code is always loaded into a domain through a .NET assembly. This is also the case when .NET code is created on the fly by compiling C# or VB code in memory. Then the .NET code is stored in a .NET assembly which is created in memory and therefrom loaded into the domain. The purpose of DotNet_LoadAssembly() is to load .NET code in a .NET assembly DLL-file into a domain. Either the default domain or a user domain. The purpose of DotNet_LoadCScode() and DotNet_LoadVBcode() is to compile C# and VB code on the fly, create a .NET assembly in memory and load the .NET code into a domain. All 3 functions returns a .NET code object which can be used in DotNet_CreateObject() to create .NET objects. When a .NET assembly is stored as a file on disk it's usually stored with a DLL- or an EXE-extension. It contains information about classes, objects, methods, properties, events, datatypes etc. concerning the resources in the assembly. It's a binary file. A .NET assembly DLL-file should not be confused with a standard DLL-file eg. a DLL-file that belongs to the Windows operating system. A .NET assembly DLL-file contains managed code. A standard DLL-file contains unmanaged code. In the same way as there are tools to extract information about the code in a standard DLL-file, there are also tools to extract information about the code in a .NET assembly DLL-file. One of these tools is ILSpy. More about ILSpy in examples section below. .NET objects Because .NET code is object-oriented code, everything is performed through objects, properties and methods. When functions are executed in .NET code, they are executed as object methods. DotNet_CreateObject() takes a .NET code object as returned by DotNet_LoadAssembly(), DotNet_LoadCScode() or DotNet_LoadVBcode() and a class name as input parameters and creates a .NET object as an instance of the class. The class must be defined in the .NET code. Now the methods of the object can be called and this executes the functions in the .NET code. Examples The Examples folder contains scripts to demonstrate the usage of the functions in DotNet.au3. In scripts where .NET code is needed for the demonstration, the code is copied from original AutoHotkey examples: An example with a XPTable.dll .NET assembly (implemented in AutoIt in this post) and two simple C# and VB code examples. I don't want to review all examples. The examples are small examples like this: #include "..\..\Includes\DotNet.au3" Opt( "MustDeclareVars", 1 ) Example() Func Example() ; Start the latest version of .NET Framework ; DotNet_Start() is automatically called by the other functions in DotNet.au3 ; You only have to call DotNet_Start() if you need an older version of .NET Framework DotNet_Start() If @error Then Return ConsoleWrite( "DotNet_Start ERR" & @CRLF ) ConsoleWrite( "DotNet_Start OK" & @CRLF ) EndFunc The example simply starts the .NET Framework from an AutoIt script. Run the examples in SciTE by pressing F5 on the keyboard. A few examples with "(compile me)" in the file name must be compiled. Run these examples by double-clicking the exe-file. ILSpy .NET assembly browser ILSpy is an open-source .NET assembly browser. Download ILSpy_Master_2.4.0.1963_Binaries.zip, unzip it and run ILSpy.exe. There is no installer. If you open \Examples\4) DotNet_LoadAssembly\XPTable.dll through the File | Open... menu you'll see this information in the right pane window: // ...\Examples\4) DotNet_LoadAssembly\XPTable.dll // XPTable, Version=1.1.0.27823, Culture=neutral, PublicKeyToken=24950705800d2198 // Global type: <Module> // Architecture: AnyCPU (64-bit preferred) // Runtime: .NET 1.1 using System; using System.Reflection; [assembly: AssemblyVersion("1.1.0.27823")] [assembly: CLSCompliant(true)] [assembly: AssemblyCompany("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCopyright("Copyright © 2005, Mathew Hall. All rights reserved.")] [assembly: AssemblyDelaySign(false)] [assembly: AssemblyDescription("A fully customisable ListView style control based on Java's JTable")] [assembly: AssemblyKeyFile("..\\..\\XPTable.snk")] [assembly: AssemblyKeyName("")] [assembly: AssemblyProduct("XPTable")] [assembly: AssemblyTitle("XPTable")] [assembly: AssemblyTrademark("")] Note the comments in the top. This line: // Architecture: AnyCPU (64-bit preferred) means that the DLL-file can be used as both a 32 and a 64 bit .NET assembly DLL-file. Using C# and VB Code in AutoIt Using C# and VB Code in AutoIt through .NET Framework is an example that uses DotNet.au3 UDF in order to be able to execute compiled C# and VB code in AutoIt scripts. Zip-file The zip-file contains two folders: Examples\ and Includes\. The project depends on eight include files of which DotNet.au3 is the actual UDF. To make it easier to use the UDF, all include files are collected in one large file: DotNetAll.au3. To use DotNet.au3 UDF in your own project just include DotNetAll.au3. You need AutoIt 3.3.10 or later. Tested on Windows 10, Windows 7 and Windows XP. Comments are welcome. Let me know if there are any issues. DotNet.7z
    5 points
  2. Tomorrow I'll add some examples that shows how to use DotNet.au3 UDF.
    2 points
  3. Bundle version 2.2 released, with @Deye's highly useful UDF filtering mod incorporated (many thanks once again for that, Deye! ), plus the (still somewhat experimental) storeCCprofile utility, with which one can extract all key definition responses on a target machine (encrypted) on a USB stick, to be uploaded on your own machine for CodeCrypter to generate an encrypted script that'll run only on that target machine (provided you're using hardware-specific keys, of course). Still with me? Not only does this facilitate the process for single keys (which you no longer have to type in twice in the dialog under the Decryptor Button), but also enables multi-key cycling for machines other than the one Codecrypter is running on, as the entire CCkey array from the target machine is now available after pressing the new "Profile" button, which uploads the (decrypted) contents of the profile.mcf file on your USB stick. Note that if you change the key definitions in MCFinclude.au3, you'll need to re-compile storeCCkey.au3 (which #includes MCFinclude.au3) as well.
    1 point
  4. Here the link for the older version including the examples: MemoryDLL_v2011.4.3.zip
    1 point
  5. Try this link: MemoryDLL_v2015.01.08.zip MemoryDll.au3 (2015.01.08) BinaryCall.au3 (2014.7.24)
    1 point
×
×
  • Create New...