Jump to content

Using .NET libary with AutoIt, possible?


Recommended Posts

I meant this.

Example2()

Func Example2()
    Local $oAssembly = _CLR_LoadLibrary("mscorlib")
    ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF)


    ; Create DateTime Object
    Local $pAssemblyType = 0
    $oAssembly.GetType_2("System.DateTime", $pAssemblyType)
    ConsoleWrite("$pAssemblyType = " & Ptr($pAssemblyType) & @CRLF)

    Local $oActivatorType = ObjCreateInterface($pAssemblyType, $sIID_IType, $sTag_IType)
    ConsoleWrite("IsObj( $oAssemblyType ) = " & IsObj($oActivatorType) & @TAB & @CRLF)

     Local $pObject = 0
     $oActivatorType.InvokeMember_3("Now", 4096, 0, 0, 0, $pObject)
    ConsoleWrite("IsObject: " & IsObj($pObject) & @TAB & "$pObject: " & $pObject & @TAB & "Name: " & ObjName($pObject) & @CRLF)
EndFunc

Saludos

Link to comment
Share on other sites

Hi Danyfirex, 

You got it working again ! :graduated:

I will never understand the magic numbers that needs to be used :(

Example1() ; System.Random

Func Example1()

    Local $oAssembly = _CLR_LoadLibrary("mscorlib")
    ConsoleWrite("!$oAssembly: " & IsObj($oAssembly) & @CRLF)

    local $oRnd =_CLR_CreateObject($oAssembly,"System.Random")
    ConsoleWrite("!$oRnd " & IsObj($oRnd) & @CRLF)

    MsgBox(0,".Net CLR Random #", "System.Random # : " & $oRnd.Next_2( 1, 100 ) & @CRLF)

EndFunc


Example2() ; System.DateTime

Func Example2()
    Local $oAssembly = _CLR_LoadLibrary("mscorlib")
    ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF)


    ; Create DateTime Object
    Local $pAssemblyType = 0
    $oAssembly.GetType_2("System.DateTime", $pAssemblyType)
    ConsoleWrite("$pAssemblyType = " & Ptr($pAssemblyType) & @CRLF)

    Local $oActivatorType = ObjCreateInterface($pAssemblyType, $sIID_IType, $sTag_IType)
    ConsoleWrite("IsObj( $oAssemblyType ) = " & IsObj($oActivatorType) & @TAB & @CRLF)

    Local $pObject = 0
    $oActivatorType.InvokeMember_3("Now", 4096, 0, 0, 0, $pObject)
    ConsoleWrite("IsObject: " & IsObj($pObject) & @TAB & "Now: " & $pObject & @TAB & "Name: " & ObjName($pObject) & @CRLF)

    MsgBox(0,"", DateStringToDateTime_EU($pObject))
EndFunc


Example3() ; System.Diagnostics.PerformanceCounter

Func Example3()

  Local $oAssembly = _CLR_LoadLibrary("System")

  ; Get an instance of the System Up Time performance counter.
  Local $Uptime = _CLR_CreateObject( $oAssembly, "System.Diagnostics.PerformanceCounter", "System", "System Up Time", "")
  ConsoleWrite( "IsObj = " & IsObj( $Uptime ) & @CRLF & @CRLF)

  ; Two read counter.
    $Uptime.NextValue();
    Local $nSecs =$Uptime.NextValue()
    $Uptime.Close()

    MsgBox(0,"System Up Time", Round($nSecs / 3600) & " Hours or " & Round($nSecs /60)& " Minutes or " & Round($nSecs) & " Seconds")
EndFunc


Example4() ; System.IO.FileInfo

Func Example4()

    Local $oAssembly = _CLR_LoadLibrary("mscorlib")
    ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF)

    local $objFileInfoClass =_CLR_CreateObject($oAssembly,"System.IO.FileInfo", @ScriptFullPath )
    ConsoleWrite("!$oRnd " & IsObj($objFileInfoClass) & @CRLF)

    MsgBox(0,".Net CLR System.IO.File #", "FileAttributes # : " & @ScriptFullPath & @CRLF)

    $Attributes = $objFileInfoClass.Attributes ;  Gets or sets the attributes for the current file or directory. (Inherited from FileSystemInfo.)
        ConsoleWrite("$Attributes: " & $Attributes & @CRLF)

    $CreationTime = $objFileInfoClass.CreationTime ;  Gets or sets the creation time of the current file or directory. (Inherited from FileSystemInfo.)
        ConsoleWrite("$CreationTime: " & DateStringToDateTime_EU($CreationTime) & @CRLF)


    $objDirectory = $objFileInfoClass.Directory ;  Gets an instance of the parent directory.
        ConsoleWrite("$objDirectory: " & $objDirectory & @CRLF)

    $DirectoryName = $objFileInfoClass.DirectoryName ;  Gets a string representing the directory's full path.
        ConsoleWrite("$DirectoryName: " & $DirectoryName & @CRLF)

    $Exists = $objFileInfoClass.Exists ;  Gets a value indicating whether a file exists. (Overrides FileSystemInfo.Exists.)
        ConsoleWrite("$Exists: " & $Exists & @CRLF)

    $Extension = $objFileInfoClass.Extension ;  Gets the string representing the extension part of the file. (Inherited from FileSystemInfo.)
        ConsoleWrite("$Extension: " & $Extension & @CRLF)

    $FullName = $objFileInfoClass.FullName ;  Gets the full path of the directory or file. (Inherited from FileSystemInfo.)
        ConsoleWrite("$FullName: " & $FullName & @CRLF)

    $IsReadOnly = $objFileInfoClass.IsReadOnly ;  Gets or sets a value that determines if the current file is read only.
        ConsoleWrite("$IsReadOnly: " &  $IsReadOnly& @CRLF)

    $LastAccessTime = $objFileInfoClass.LastAccessTime ;  Gets or sets the time the current file or directory was last accessed. (Inherited from FileSystemInfo.)
        ConsoleWrite("$LastAccessTime: " & DateStringToDateTime_EU($LastAccessTime) & @CRLF)


    $LastWriteTime = $objFileInfoClass.LastWriteTime ;  Gets or sets the time when the current file or directory was last written to. (Inherited from FileSystemInfo.)
        ConsoleWrite("$LastWriteTime: " & DateStringToDateTime_EU($LastWriteTime) & @CRLF)


    $Length = $objFileInfoClass.Length ;  Gets the size, in bytes, of the current file
        ConsoleWrite("$Length: " & $Length & @CRLF)

    $Name = $objFileInfoClass.Name ;  Gets the name of the file. (Overrides FileSystemInfo.Name.)
        ConsoleWrite("$Name: " & $Name & @CRLF)
EndFunc   ;==>_Example1

Func DateStringToDateTime_EU($dtmDate)
    Return(StringRegExpReplace($dtmDate, "\A(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(?:.*)","$1/$2/$3 $4:$5:$6"))
EndFunc

Func DateStringToDateTime_US($dtmDate)
    Return(StringRegExpReplace($dtmDate, "\A(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})(?:.*)","$2/$3/$1 $4:$5:$6"))
EndFunc


Example5() ; System.Int32

Func Example5()

    ; Convert DateTime to a CLR DateTime Object
    $aDate = _Date_Time_DOSDateTimeToArray(0x3621, 0x944a) ; 01/01/2007 18:34:20
    ConsoleWrite("FAT date .: " & StringFormat("%02d/%02d/%04d", $aDate[0], $aDate[1], $aDate[2]) & @CRLF)
    ConsoleWrite("FAT time .: " & StringFormat("%02d:%02d:%02d", $aDate[3], $aDate[4], $aDate[5]) & @CRLF & @CRLF)

    ; Call CLR Libr.
    Local $oAssembly = _CLR_LoadLibrary("mscorlib")
    ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF)

    ; Create Object System.Int32 (or Double)
    Local $pAssemblyType = 0
    $oAssembly.GetType_2("System.Int32", $pAssemblyType)
    ConsoleWrite("$pAssemblyType = " & Ptr($pAssemblyType) & @CRLF)

    Local $oAssemblyType = ObjCreateInterface($pAssemblyType, $sIID_IType, $sTag_IType)
    ConsoleWrite("IsObj( $oAssemblyType ) = " & IsObj($oAssemblyType) & @CRLF)

    ; Parse Month Text as Int32
    Local $iMonth = 0
    Local $objMonth[] = [ String($aDate[0]) ]

    $oAssemblyType.InvokeMember_3("Parse", 0x158, 0, 0, CreateSafeArray($objMonth), $iMonth)
    ConsoleWrite("$iMonth : " & $iMonth & @CRLF)

    ; Parse Day Text as Int32
    Local $iDay = 0
    Local $objDay[] = [ String($aDate[1]) ]

    $oAssemblyType.InvokeMember_3("Parse", 0x158, 0, 0, CreateSafeArray($objDay), $iDay)
    ConsoleWrite("$iDay : " & $iDay & @CRLF)

    ; Parse Year Text as Int32
    Local $iYear = 0
    Local $objYear[] = [ String($aDate[2]) ]

    $oAssemblyType.InvokeMember_3("Parse", 0x158, 0, 0, CreateSafeArray($objYear), $iYear)
    ConsoleWrite("$iYear : " & $iYear & @CRLF)

    ; Parse Hour Text as Int32
    Local $iHour = 0
    Local $objHour[] = [ String($aDate[3]) ]

    $oAssemblyType.InvokeMember_3("Parse", 0x158, 0, 0, CreateSafeArray($objHour), $iHour)
    ConsoleWrite("$iHour : " & $iHour & @CRLF)

    ; Parse Min Text as Int32
    Local $iMin = 0
    Local $objMin[] = [ String($aDate[4]) ]

    $oAssemblyType.InvokeMember_3("Parse", 0x158, 0, 0, CreateSafeArray($objMin), $iMin)
    ConsoleWrite("$iMin : " & $iMin & @CRLF)

    ; Parse Sec Text as Int32
    Local $iSec = 0
    Local $objSec[] = [ String($aDate[5]) ]

    $oAssemblyType.InvokeMember_3("Parse", 0x158, 0, 0, CreateSafeArray($objSec), $iSec)
    ConsoleWrite("$iSec : " & $iSec & @CRLF)
    ConsoleWrite(@CRLF)

EndFunc


Example6() ; System.Double

Func Example6()
    Local $oAssembly = _CLR_LoadLibrary("mscorlib")
    ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF)

    ; Create Double Object
    Local $pAssemblyType = 0
    $oAssembly.GetType_2("System.Double", $pAssemblyType)
    ConsoleWrite("$pAssemblyType = " & Ptr($pAssemblyType) & @CRLF)

    Local $oActivatorType = ObjCreateInterface($pAssemblyType, $sIID_IType, $sTag_IType)
    ConsoleWrite("IsObj( $oAssemblyType ) = " & IsObj($oActivatorType) & @TAB & @CRLF)

    Local $aText[] = ["12,125"]
    Local $iDouble = 0
    $oActivatorType.InvokeMember_3("Parse", 0x158, 0, 0, CreateSafeArray($aText), $iDouble)

    ConsoleWrite("Double : " & $iDouble & @CRLF)
    ConsoleWrite(@CRLF)
EndFunc

So in total we have now 6 extra working Examples running ! :)

Which I can add in the next coming days to the release if that is OK for you all ?

 

Link to comment
Share on other sites

Here is the magic numbers Info.

 

// Summary:
    //     Specifies no binding flag.
    Default = 0,
    //
    // Summary:
    //     Specifies that the case of the member name should not be considered when
    //     binding.
    IgnoreCase = 1,
    //
    // Summary:
    //     Specifies that only members declared at the level of the supplied type's
    //     hierarchy should be considered. Inherited members are not considered.
    DeclaredOnly = 2,
    //
    // Summary:
    //     Specifies that instance members are to be included in the search.
    Instance = 4,
    //
    // Summary:
    //     Specifies that static members are to be included in the search.
    Static = 8,
    //
    // Summary:
    //     Specifies that public members are to be included in the search.
    Public = 16,
    //
    // Summary:
    //     Specifies that non-public members are to be included in the search.
    NonPublic = 32,
    //
    // Summary:
    //     Specifies that public and protected static members up the hierarchy should
    //     be returned. Private static members in inherited classes are not returned.
    //     Static members include fields, methods, events, and properties. Nested types
    //     are not returned.
    FlattenHierarchy = 64,
    //
    // Summary:
    //     Specifies that a method is to be invoked. This must not be a constructor
    //     or a type initializer.
    InvokeMethod = 256,
    //
    // Summary:
    //     Specifies that Reflection should create an instance of the specified type.
    //     Calls the constructor that matches the given arguments. The supplied member
    //     name is ignored. If the type of lookup is not specified, (Instance | Public)
    //     will apply. It is not possible to call a type initializer.
    CreateInstance = 512,
    //
    // Summary:
    //     Specifies that the value of the specified field should be returned.
    GetField = 1024,
    //
    // Summary:
    //     Specifies that the value of the specified field should be set.
    SetField = 2048,
    //
    // Summary:
    //     Specifies that the value of the specified property should be returned.
    GetProperty = 4096,
    //
    // Summary:
    //     Specifies that the value of the specified property should be set. For COM
    //     properties, specifying this binding flag is equivalent to specifying PutDispProperty
    //     and PutRefDispProperty.
    SetProperty = 8192,
    //
    // Summary:
    //     Specifies that the PROPPUT member on a COM object should be invoked. PROPPUT
    //     specifies a property-setting function that uses a value. Use PutDispProperty
    //     if a property has both PROPPUT and PROPPUTREF and you need to distinguish
    //     which one is called.
    PutDispProperty = 16384,
    //
    // Summary:
    //     Specifies that the PROPPUTREF member on a COM object should be invoked. PROPPUTREF
    //     specifies a property-setting function that uses a reference instead of a
    //     value. Use PutRefDispProperty if a property has both PROPPUT and PROPPUTREF
    //     and you need to distinguish which one is called.
    PutRefDispProperty = 32768,
    //
    // Summary:
    //     Specifies that types of the supplied arguments must exactly match the types
    //     of the corresponding formal parameters. Reflection throws an exception if
    //     the caller supplies a non-null Binder object, since that implies that the
    //     caller is supplying BindToXXX implementations that will pick the appropriate
    //     method.
    ExactBinding = 65536,
    //
    // Summary:
    //     Not implemented.
    SuppressChangeType = 131072,
    //
    // Summary:
    //     Returns the set of members whose parameter count matches the number of supplied
    //     arguments. This binding flag is used for methods with parameters that have
    //     default values and methods with variable arguments (varargs). This flag should
    //     only be used with System.Type.InvokeMember(System.String,System.Reflection.BindingFlags,System.Reflection.Binder,System.Object,System.Object[],System.Reflection.ParameterModifier[],System.Globalization.CultureInfo,System.String[]).
    OptionalParamBinding = 262144,
    //
    // Summary:
    //     Used in COM interop to specify that the return value of the member can be
    //     ignored.
    IgnoreReturn = 16777216,

I'll check System.Diagnostics.Process example later.

 

Saludos

Link to comment
Share on other sites

 

 

 

Link to comment
Share on other sites

Thanks a lot !!

This is also some useful info I found on the net :

Quote

http://www.informit.com/articles/article.aspx?p=27219&seqNum=8

 

Table 3.1 .NET Types and Their Marshaling Behavior Inside VARIANTs

 

Type of Instance

VARIANT Type

null (Nothing in VB .NET)

VT_EMPTY

System.DBNull

VT_NULL

System.Runtime.InteropServices.CurrencyWrapper

VT_CY

System.Runtime.InteropServices.UnknownWrapper

VT_UNKNOWN

System.Runtime.InteropServices.DispatchWrapper

VT_DISPATCH

System.Runtime.InteropServices.ErrorWrapper

VT_ERROR

System.Reflection.Missing

-VT_ERROR with value DISP_E_PARAMNOTFOUND

System.String

VT_BSTR

System.Decimal

VT_DECIMAL

System.Boolean

VT_BOOL

System.Char

VT_U2

System.Byte

VT_U1

System.SByte

VT_I1

System.Int16

VT_I2

System.Int32

VT_I4

System.Int64

VT_I8

System.IntPtr

VT_INT

System.UInt16

VT_U2

System.UInt32

VT_U4

System.UInt64

VT_U8

System.UIntPtr

VT_UINT

System.Single

VT_R4

System.Double

VT_R8

System.DateTime

VT_DATE

Any Array

VT_... | VT_ARRAY

System.Object or other .NET classes

VT_DISPATCH


An array of strings appears as VT_BSTR | VT_ARRAY, an array of doubles appears as VT_R8 | VT_ARRAY, and so on. The VT_I8 and VT_U8 VARIANT types listed in Table 3.1 are not supported prior to Windows XP. Also, notice that in version 1.0 the Interop Marshaler does not support VARIANTs with the VT_RECORD type (used for user-defined structures).

 

 

Link to comment
Share on other sites

Sure no hurries... I keep on creating  trial and error Examples ...

Mayby we should start replacing the magic numbers by vars names, as this is more appealing and complies to better to the better coding practices... ?

Some home works before we release the next version...

 

Link to comment
Share on other sites

  • Example to try (No AutoIt at hand right now) which then also should work for those progid's not in registry
$handle = Activator.CreateComInstanceFrom("Microsoft.mshtml.dll", "mshtml.HTMLDocumentClass")
$obj = $handle.Unwrap(); 
//The result is "mshtml.HTMLDocumentClass" 
ConsoleWriteLine($obj.ToString())
  • Some special things I was reading
    Special cases
    With the methods presented earlier you can create an instance of almost any kind of class or structure.
    Two special cases
    1. To create an array you must call cthe createinstance() static method of the system.array class
    2. To create a delegate object you must call the createdelegate() method of the system.delegate class

 

 

Link to comment
Share on other sites

Tried something like this but no success ?

Example1()

Func Example1()
    Local $oAssembly = _CLR_LoadLibrary("mscorlib")
    ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF)

    ; Create Double Object
    Local $pAssemblyType = 0
    $oAssembly.GetType_2("System.Activator", $pAssemblyType)
    ConsoleWrite("$pAssemblyType = " & Ptr($pAssemblyType) & @CRLF)

    Local $oActivatorType = ObjCreateInterface($pAssemblyType, $sIID_IType, $sTag_IType)
    ConsoleWrite("IsObj( $oAssemblyType ) = " & IsObj($oActivatorType) & @TAB & @CRLF)


    $handle = $oActivatorType.CreateComInstanceFrom("C:\Windows\assembly\GAC\Microsoftmshtml\7.0.3300.0_b03f5f7flld50a3a\Microsoft.mshtml.dll", "mshtml.HTMLDocumentClass")
    $obj = $handle.Unwrap();
    ; //The result is "mshtml.HTMLDocumentClass"
    ConsoleWrite($obj.ToString() & @CRLF)
EndFunc

Error :

err.number is:         0x80020006
    err.windescription:    Unknown name.

    err.description is:     
    err.source is:         
    err.helpfile is:     
    err.helpcontext is:     
    err.lastdllerror is:     0
    err.scriptline is:     18
    err.retcode is:     0x00000000

Link to comment
Share on other sites

Try this:

 

#include ".\Includes\CLR.au3"
Global $sHTML = '<!DOCTYPE html>' & @CR
            $sHTML &= '<html>' & @CR
            $sHTML &= '<head>' & @CR
            $sHTML &= '<meta content="text/html; charset=UTF-8" http-equiv="content-type">' & @CR
            $sHTML &= '<title>_IE_Introduction ("basic")</title>' & @CR
            $sHTML &= '<style>body {font-family: Arial}' & @CR
            $sHTML &= 'td {padding:6px}</style>' & @CR
            $sHTML &= '</head>' & @CR
            $sHTML &= '<body>' & @CR
            $sHTML &= '<table border=1 id="table1" style="width:600px;border-spacing:6px;">' & @CR
            $sHTML &= '<tr>' & @CR
            $sHTML &= '<td>' & @CR
            $sHTML &= '<h1>Welcome to IE.au3</h1>' & @CR
            $sHTML &= 'IE.au3 is a UDF (User Defined Function) library for the ' & @CR
            $sHTML &= '<a href="http://www.autoitscript.com">AutoIt</a> scripting language.' & @CR
            $sHTML &= '<br>  ' & @CR
            $sHTML &= 'IE.au3 allows you to either create or attach to an Internet Explorer browser and do ' & @CR
            $sHTML &= 'just about anything you could do with it interactively with the mouse and ' & @CR
            $sHTML &= 'keyboard, but do it through script.' & @CR
            $sHTML &= '<br>' & @CR
            $sHTML &= 'You can navigate to pages, click links, fill and submit forms etc. You can ' & @CR
            $sHTML &= 'also do things you cannot do interactively like change or rewrite page ' & @CR
            $sHTML &= 'content and JavaScripts, read, parse and save page content and monitor and act ' & @CR
            $sHTML &= 'upon browser "events".<br>' & @CR
            $sHTML &= 'IE.au3 uses the COM interface in AutoIt to interact with the Internet Explorer ' & @CR
            $sHTML &= 'object model and the DOM (Document Object Model) supported by the browser.' & @CR
            $sHTML &= '<br>' & @CR
            $sHTML &= 'Here are some links for more information and helpful tools:<br>' & @CR
            $sHTML &= 'Reference Material: ' & @CR
            $sHTML &= '<ul>' & @CR
            $sHTML &= '<li><a href="http://msdn1.microsoft.com/">MSDN (Microsoft Developer Network)</a></li>' & @CR
            $sHTML &= '<li><a href="http://msdn2.microsoft.com/en-us/library/aa752084.aspx" target="_blank">InternetExplorer Object</a></li>' & @CR
            $sHTML &= '<li><a href="http://msdn2.microsoft.com/en-us/library/ms531073.aspx" target="_blank">Document Object</a></li>' & @CR
            $sHTML &= '<li><a href="http://msdn2.microsoft.com/en-us/ie/aa740473.aspx" target="_blank">Overviews and Tutorials</a></li>' & @CR
            $sHTML &= '<li><a href="http://msdn2.microsoft.com/en-us/library/ms533029.aspx" target="_blank">DHTML Objects</a></li>' & @CR
            $sHTML &= '<li><a href="http://msdn2.microsoft.com/en-us/library/ms533051.aspx" target="_blank">DHTML Events</a></li>' & @CR
            $sHTML &= '</ul><br>' & @CR
            $sHTML &= 'Helpful Tools: ' & @CR
            $sHTML &= '<ul>' & @CR
            $sHTML &= '<li><a href="http://www.autoitscript.com/forum/index.php?showtopic=19368" target="_blank">AutoIt IE Builder</a> (build IE scripts interactively)</li>' & @CR
            $sHTML &= '<li><a href="http://www.debugbar.com/" target="_blank">DebugBar</a> (DOM inspector, HTTP inspector, HTML validator and more - free for personal use) Recommended</li>' & @CR
            $sHTML &= '<li><a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=e59c3964-672d-4511-bb3e-2d5e1db91038&amp;displaylang=en" target="_blank">IE Developer Toolbar</a> (comprehensive DOM analysis tool)</li>' & @CR
            $sHTML &= '<li><a href="http://slayeroffice.com/tools/modi/v2.0/modi_help.html" target="_blank">MODIV2</a> (view the DOM of a web page by mousing around)</li>' & @CR
            $sHTML &= '<li><a href="http://validator.w3.org/" target="_blank">HTML Validator</a> (verify HTML follows format rules)</li>' & @CR
            $sHTML &= '<li><a href="http://www.fiddlertool.com/fiddler/" target="_blank">Fiddler</a> (examine HTTP traffic)</li>' & @CR
            $sHTML &= '</ul>' & @CR
            $sHTML &= '</td>' & @CR
            $sHTML &= '</tr>' & @CR
            $sHTML &= '</table>' & @CR
            $sHTML &= '</body>' & @CR
            $sHTML &= '</html>'

Example()

Func Example()

    Local $oAssembly = _CLR_LoadLibrary("mscorlib")
    ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF)

    Local $pAssemblyType = 0
    $oAssembly.GetType_2("System.Activator", $pAssemblyType)
    ConsoleWrite("$pAssemblyType = " & Ptr($pAssemblyType) & @CRLF)

    Local $oAssemblyType = ObjCreateInterface($pAssemblyType, $sIID_IType, $sTag_IType)
    ConsoleWrite("IsObj( $oAssemblyType ) = " & IsObj($oAssemblyType) & @TAB & @CRLF)

    Local $aText[] = ["C:\Program Files (x86)\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dll", "mshtml.HTMLDocumentClass"] ;Set correct assembly path
    Local $pObject = 0
    $oAssemblyType.InvokeMember_3("CreateComInstanceFrom", 0x158, 0, 0, CreateSafeArray($aText), $pObject)
    ConsoleWrite("IsObject: " & IsObj($pObject) & @TAB & "$pObject: " & ObjName($pObject) & @CRLF)

    Local $oHTMLDocumentClass = $pObject.Unwrap()
    ConsoleWrite("!$oHTMLDocumentClass: " & IsObj($oHTMLDocumentClass) & @CRLF)
    $oHTMLDocumentClass.write($sHTML)

    Local $oLinks=$oHTMLDocumentClass.Links
    For $oLink in $oLinks
        ConsoleWrite($oLink.ToString() & @CRLF)
    Next

EndFunc   ;==>Example

lol what I'm doing here at 4 am 

Saludos

Link to comment
Share on other sites

Link to comment
Share on other sites

Link to comment
Share on other sites

Another simple Example :

Example()

Func Example()
    Local $oAssembly = _CLR_LoadLibrary("System.Speech")
    ConsoleWrite("!$oAssembly: " & IsObj($oAssembly) & @CRLF)

    local $oSpeech =_CLR_CreateObject($oAssembly,"System.Speech.Synthesis.SpeechSynthesizer")
    ConsoleWrite("!$oOptions " & IsObj($oSpeech) & @CRLF)

    $cVoice = ""
    $cName=$oSpeech.Voice.Name
    $cVoice=$cVoice&"Name: "&$cName&@CRLF
    $cVoice=$cVoice&"Culture: "&$oSpeech.Voice.Culture&@CRLF
    $cVoice=$cVoice&"Age: "&$oSpeech.Voice.Age&@CRLF
    $cVoice=$cVoice&"Gender: "&$oSpeech.Voice.Gender&@CRLF
    $cVoice=$cVoice&"Description: "&$oSpeech.Voice.Description&@CRLF
    $cVoice=$cVoice&"ID: "&$oSpeech.Voice.Id&@CRLF

    ConsoleWrite( $cVoice& @CRLF)

    ; This will obtain an object, you can iterate with a For Next
    ; If oSpeech.Voice.SupportedAudioFormats.Count != 0 Then cVoice=cVoice:"Audio Formats: ":oSpeech.Voice.SupportedAudioFormats:@CRLF

    $oSpeech.SelectVoice($cName)
    $oSpeech.Speak("This is a Test - AutoIT Rocks !")
    $oSpeech.Dispose()
    $oSpeech=0
        MsgBox(0,"System.Speech","We just spoke ! ")
EndFunc

 

Link to comment
Share on other sites

One more to go  :

Example4() ; System.Web

Func Example4()
    Local $oAssembly = _CLR_LoadLibrary("System.Web")
    ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF)

    ; Create DateTime Object
    Local $pAssemblyType = 0
    $oAssembly.GetType_2("System.Web.Security.Membership", $pAssemblyType)
    ConsoleWrite("$pAssemblyType = " & Ptr($pAssemblyType) & @CRLF)

    Local $oActivatorType = ObjCreateInterface($pAssemblyType, $sIID_IType, $sTag_IType)
    ConsoleWrite("IsObj( $oAssemblyType ) = " & IsObj($oActivatorType) & @TAB & @CRLF)

    Local $aText[] = [8,3] ; Length = 8 , NumNonAlpha = 3
    Local $oMembership = 0
    $oActivatorType.InvokeMember_3("GeneratePassword", 0x158, 0, 0, CreateSafeArray($aText), $oMembership)
    ConsoleWrite("IsObj( $oAssemblyType ) = " & IsObj($oMembership) & @TAB & @CRLF)

    ConsoleWrite("Pswd: " & $oMembership  &@CRLF)
    MsgBox(0,"System.Web.Security.Membership","Generated Pswd : " & $oMembership)
EndFunc

 

Link to comment
Share on other sites

CLR Late Binding :

Quote

Late Binding

Reflection can also perform late binding, in which the application dynamically loads, instantiates and uses a type at runtime. 
This provides greater flexibility at the expense of invocation overhead.

The Activator class contains four methods, all static, which you can use to create objects locally or remotely
or to obtain references to existing objects.

The four methods are CreateComInstanceFrom, CreateInstanceFrom, GetObject, and CreateInstance:

  • 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.

 

So at the moment we have examples where we use CreateInstance and CreateComInstanceFrom, correct ?

Link to comment
Share on other sites

Still struggling to get the Array Output returned though, anyone ?

Func Example()
    Local $oAssembly = _CLR_LoadLibrary("System")
    ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF)

    Local $pAssemblyType = 0
    $oAssembly.GetType_2("System.Diagnostics.Process", $pAssemblyType)
    ConsoleWrite("$pAssemblyType = " & Ptr($pAssemblyType) & @CRLF)

    Local $oAssemblyType = ObjCreateInterface($pAssemblyType, $sIID_IType, $sTag_IType)
    ConsoleWrite("IsObj( $oAssemblyType ) = " & IsObj($oAssemblyType) & @CRLF)

    Local $strProcName[] = ["Notepad"]
    Local $pObject = 0
    $oAssemblyType.InvokeMember_3("GetProcessesByName", 0x158, 0, 0,CreateSafeArray($strProcName), $pObject); $oAssemblyType.GetProcessesByName($strProcName)
    ConsoleWrite("Array : " & Isobj($pObject) & @CRLF)

    Local $vt=0
    SafeArrayGetVartype($pObject, $vt)
    ConsoleWrite("$vt = " & $vt & @CRLF)

    ; https://msdn.microsoft.com/en-us/library/cc237825.aspx
    ; SF_UNKNOWN:  The type of the elements contained in the SAFEARRAY MUST be a pointer to IUnknown.
    ; Hex value is 0x0000000D.
    ; Element marshaling size in bytes: 4
    
    ; ....
EndFunc

 

Link to comment
Share on other sites

Here you have.

 

#include ".\Includes\CLR.Au3"


Example()

Func Example()
    Local $oAssembly = _CLR_LoadLibrary("System")
    ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF)

    Local $pAssemblyType = 0
    $oAssembly.GetType_2("System.Diagnostics.Process", $pAssemblyType)
    ConsoleWrite("$pAssemblyType = " & Ptr($pAssemblyType) & @CRLF)

    Local $oAssemblyType = ObjCreateInterface($pAssemblyType, $sIID_IType, $sTag_IType)
    ConsoleWrite("IsObj( $oAssemblyType ) = " & IsObj($oAssemblyType) & @CRLF)


    Local $sName = ""
    $oAssemblyType.get_FullName($sName)
    ConsoleWrite($sName & @CRLF)
    Local $strProcName[] = ["Notepad"]
    Local $pObject = 0


  ;Run two Notepad instances
   $oAssemblyType.InvokeMember_3("Start", 0x158, 0, 0, CreateSafeArray($strProcName), $pObject)
   $oAssemblyType.InvokeMember_3("Start", 0x158, 0, 0, CreateSafeArray($strProcName), $pObject)
   Sleep(1000)

    $oAssemblyType.InvokeMember_3("GetProcessesByName", 0x158, 0, 0, CreateSafeArray($strProcName), $pObject)
    ConsoleWrite("$pObject: " & IsObj($pObject) & @TAB & "$pObject: " & Ptr($pObject) & @CRLF)

    Local $pProcess = $pObject
    ConsoleWrite("$pProcess = " & Ptr($pProcess) & @CRLF)
    Local $iDim = SafeArrayGetDim($pProcess)
    ConsoleWrite("$iDim = " & $iDim & @CRLF)

    Local $iLBound, $iUBound
    SafeArrayGetLBound($pProcess, 1, $iLBound)
    SafeArrayGetUBound($pProcess, 1, $iUBound)
    ConsoleWrite("$iLBound = " & $iLBound & @CRLF)
    ConsoleWrite("$iUBound = " & $iUBound & @CRLF)

    Local $tTypeArray = DllStructCreate($tagSAFEARRAY, $pProcess)
    Local $iPtrSize = (DllStructGetData($tTypeArray, "cbElements"))

    ConsoleWrite(".cDims = " & (DllStructGetData($tTypeArray, "cDims")) & @CRLF & @CRLF)
    ConsoleWrite(".fFeatures = 0x" & Hex(DllStructGetData($tTypeArray, "fFeatures")) & @CRLF)
    ConsoleWrite(".cbElements = " & $iPtrSize & @CRLF)
    Local $vt = 0
    SafeArrayGetVartype($pProcess, $vt)
    ConsoleWrite("$vt = " & $vt & @CRLF)


    Local $paProcessArrayData = 0
    Local $tProcess = 0
    Local $poProcess = 0
    Local $oProcess = Null

    SafeArrayAccessData($pProcess, $paProcessArrayData)
    For $i = 0 To $iUBound
        $tProcess = DllStructCreate("ptr", $paProcessArrayData + ($i * $iPtrSize))
        $poProcess = DllStructGetData($tProcess, 1)
        ConsoleWrite("+$poProcess = " & $poProcess & @CRLF)

        $oProcess = ObjCreateInterface($poProcess,"",Default,False)
        ConsoleWrite("IsObj( $oProcess ) = " & IsObj($oProcess) & @CRLF)
        ConsoleWrite("-Process " & $i+1 & " Information" & @CRLF)
        ConsoleWrite("$oProcess.ProcessName : " & $oProcess.ProcessName & @CRLF)
        ConsoleWrite("$oProcess.Id : " & $oProcess.Id & @CRLF)
        ConsoleWrite("$oProcess.MainWindowTitle : " & $oProcess.MainWindowTitle & @CRLF)
        ConsoleWrite(@CRLF)

        $poProcess = 0
        $tProcess = 0
        $oProcess = Null
    Next
    SafeArrayUnaccessData($pProcess)

EndFunc   ;==>Example

Saludos

Link to comment
Share on other sites

Small function to get activator as it will be an important part of creating instances

func getActivator()
    Local $oAssembly = _CLR_LoadLibrary("mscorlib")
    Local $ptActivator = 0
    $oAssembly.GetType_2("System.Activator", $ptActivator)
    Local $oActivator = ObjCreateInterface($ptActivator, $sIID_IType, $sTag_IType)

;~  ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF)
;~  ConsoleWrite("$pAssemblyType = " & Ptr($ptActivator) & @CRLF)
;~  ConsoleWrite("IsObj( $oAssemblyType ) = " & IsObj($oActivator) & @TAB & @CRLF)

    return $oActivator
endfunc

This how to use but still have an issue with the path and using the createcominstancefrom (it works fine with the htmldocumentclass)

Func Example()
    local $oActivator=getActivator()

;~  Local $oAssembly = _CLR_LoadLibrary("System.Web")
;~  ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF)

    Local $aText[] = ["C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Web.dll", "System.Web.Security.Membership"] ;Set correct assembly path
;~ Local $aText[] = ["C:\Program Files (x86)\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dll", "mshtml.HTMLDocumentClass"]
Local $pObject = 0

    $oActivator.InvokeMember_3("CreateComInstanceFrom", 0x158, 0, 0, CreateSafeArray($aText), $pObject)
    ConsoleWrite("IsObject: " & IsObj($pObject) & @TAB & "$pObject: " & ObjName($pObject) & @CRLF)

    Local $oMembership = $pObject.Unwrap()
    ConsoleWrite("!$oMembership: " & IsObj($oMembership) & @CRLF)
    consolewrite($oMembership.GeneratePassword(8,3))

EndFunc   ;==>Example

and not sure if this will work to make activator a COM version (fails now no clue why as system.activator has comvisible=true)

func getActivatorCOM()
    local $oActivator=getActivator()

    ConsoleWrite("IsObj( $oActivator) = " & IsObj($oActivator) & @TAB & @CRLF)
    Local $aText[] = ["mscorlib.dll", "System.Activator"] ;Set correct assembly path
    Local $pObject = 0
    $oActivator.InvokeMember_3("CreateComInstanceFrom", 0x158, 0, 0, CreateSafeArray($aText), $pObject)
    ConsoleWrite("IsObject: " & IsObj($pObject) & @TAB & "$pObject: " & ObjName($pObject) & @CRLF)

    Local $oActivatorCom= $pObject.Unwrap()
    ConsoleWrite("!$oActivatorCom: " & IsObj($oActivatorCom) & @CRLF)
    return $oActivatorCOM
EndFunc

 

Link to comment
Share on other sites

Hi Junkew,

I will play around with your example to see what it does later this weekend.

Hi Danyfirex, Thanks again for sharing your expertise !!

We learn a lot from these examples ...:)

But then again it is also a bit confusing because there seem to be different approaches that need to be used depending on the case.

For Example, why "get_FullName" is needed and we can't just use '$oProcess.ProcessName' from the Object returned straight away ...? 

Also the Safe Arrays stuff seems so overcomplicated to get some data returned, for such a simple method.

Should we not try to simplify things ... 

1. Isn't there a way to move the SafeArray stuff to the background into the CLR.au3 UDF  and call it through a simplified function ?

2. Or can we use conventional COM using the Objcreate("System.Collections.ArrayList")  to pass data back and forth to .NET ? Needed testing ....

3. Next thing I we need to do is to Global Contants for the MAGIC numbers...

4. Agree on a coding conversion for the variables

5. Rework the examples and publish a new version...

Input is welcome ...

In the meantime I will create more examples (and ask for support where needed  :yawn:

Link to comment
Share on other sites

Junkew,

I did a few test with Assemblies that are fully COM Compatible and they work fine.

Like WinSCP

Example() ; WinSCP

Func Example()
    local $oActivator=getActivator()

    Local $aText[] = ["C:\_\Apps\_PowerShell\_WinSCP Assembly\WinSCPnet.dll", "WinSCP.Session"] ;Set correct assembly path

    Local $pObject = 0
    $oActivator.InvokeMember_3("CreateComInstanceFrom", 0x158, 0, 0, CreateSafeArray($aText), $pObject)
    ConsoleWrite("IsObject: " & IsObj($pObject) & @TAB & "$pObject: " & ObjName($pObject) & @CRLF)

    Local $oObject = $pObject.Unwrap()
    ConsoleWrite("!$oMembership: " & IsObj($oObject) & @CRLF)
    consolewrite("!IsSession : " & $oObject.Opened & @CRLF)
;~  consolewrite("!IsProtocol : " & $oObject.FileExists("WinSCPnet.dll") & @CRLF)

EndFunc   ;==>Example

So my guess is that this method can only be used when you have Assemblies that are fully COM Visible AND registered via REGASM ?

This make that only a subset of Assemblies can be used, using "CreateComInstanceFrom:(

 

Link to comment
Share on other sites

Safearrays can be handled in more or less smarter ways. The smart way is demonstrated in Accessing AutoIt Variables. The required code is contained in the zip below.

Now the code in post 276 looks like this:

;#AutoIt3Wrapper_UseX64=y

#include "CLR.au3"
#include "AccVarsUtilities.au3"


Example()

Func Example()
  Local $oAssembly = _CLR_LoadLibrary("System")
  ConsoleWrite("$oAssembly: " & IsObj($oAssembly) & @CRLF)

  Local $pAssemblyType = 0
  $oAssembly.GetType_2("System.Diagnostics.Process", $pAssemblyType)
  ConsoleWrite("$pAssemblyType = " & Ptr($pAssemblyType) & @CRLF)

  Local $oAssemblyType = ObjCreateInterface($pAssemblyType, $sIID_IType, $sTag_IType)
  ConsoleWrite("IsObj( $oAssemblyType ) = " & IsObj($oAssemblyType) & @CRLF)

  Local $sName = ""
  $oAssemblyType.get_FullName($sName)
  ConsoleWrite($sName & @CRLF)
  Local $strProcName[] = ["Notepad"], $pSafeArray
  AccVars_ArrayToSafeArray( $strProcName, $pSafeArray ) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  Local $pObject = 0, $aObject, $oProcess

  ; Run two Notepad instances
  $oAssemblyType.InvokeMember_3("Start", 0x158, 0, 0, $pSafeArray, $pObject)
  $oAssemblyType.InvokeMember_3("Start", 0x158, 0, 0, $pSafeArray, $pObject)
  Sleep(1000)

  $oAssemblyType.InvokeMember_3("GetProcessesByName", 0x158, 0, 0, $pSafeArray, $pObject)
  ConsoleWrite("$pObject: " & IsObj($pObject) & @TAB & "$pObject: " & Ptr($pObject) & @CRLF & @CRLF)

  AccVars_SafeArrayToArray( $pObject, $aObject ) ; <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

  For $i = 0 To UBound( $aObject ) - 1
    $oProcess = ObjCreateInterface($aObject[$i],"",Default,False)
    ConsoleWrite("IsObj( $oProcess ) = " & IsObj($oProcess) & @CRLF)
    ConsoleWrite("-Process " & $i+1 & " Information" & @CRLF)
    ConsoleWrite("$oProcess.ProcessName : " & $oProcess.ProcessName & @CRLF)
    ConsoleWrite("$oProcess.Id : " & $oProcess.Id & @CRLF)
    ConsoleWrite("$oProcess.MainWindowTitle : " & $oProcess.MainWindowTitle & @CRLF)
    ConsoleWrite(@CRLF)
  Next
EndFunc


The code in Accessing AutoIt Variables exploits conversions in internal AutoIt code that takes place between native AutoIt arrays and safearrays in relation to COM objects. The following variant types are directly supported by those conversions: VT_I2, VT_I4, VT_R4, VT_R8, VT_BSTR, VT_BOOL, VT_UI4, VT_UI8 and VT_VARIANT. But VT_UNKNOWN which is used in post 276 is not supported. I've added code to support this type.

In AutoIt there is no easy way to deal with safearrays. You can either do something like this, or you can access the variant and safearray data structures directly. The classes in System.Collections namespace is not a workaround.

I've only tested the code in post 276. Let me know if there are any issues.

AccessingVariables.7z

Edited by LarsJ
Forgot to replace the last CreateSafeArray
Link to comment
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
 Share

×
×
  • Create New...