Einbinden einer DLL in AutoIT (VMware VIX)

  • Ähm .... BAHNHOF ....


    Wenn die Funktionen nach den C Aufrufkonventionen deklariert sind, dann musst du dem Rückgabewert der Funktion im DllCall ein "cdecl:" voranstellen.
    Also z.B.:

    Spoiler anzeigen
    [autoit]

    Local $aRes = DllCall ($vixdll, "cdecl:INT", "VixHost_Connect", _
    "INT", $apiVersion, _
    "INT", $hostType, _
    "str", $hostName, _
    "INT", $hostPort, _
    "str", $userName, _
    "str", $password, _
    "INT", $options, _
    "INT", $propertyListHandle, _
    "PTR", $callbackProc, _
    "PTR", $clientData)

    [/autoit]


    Gruß
    Greenhorn


  • Wenn die Funktionen nach den C Aufrufkonventionen deklariert sind, dann musst du den Rückgabewert der Funktion im DllCall ein "cdecl:" voranstellen.


    Nein, :cdecl muss hinter den Rückgabewert.
    DllCall($dll, "INT:cdecl", "Funktion", ...

    Klar ist extern "C" kein wirklicher Hinweis. Es steht aber extern C da und es crasht mit stdcall --> Dann ist es mit großer Wahrscheinlichkeit C-Konvention

  • Ha! es geht im Moment ohne Abstürze!

    Ich habe neben der vix.dll alle anderen .dll Dateien die ebenfalls im entsprechenden VIX Verzeichnis waren auch kopiert.
    Aus Verzweiflung habe ich mit einem DLL Explorer mal in die Dinger reingeschaut.
    getestet habe ich (mit der ja auch Dokumentierten) vix.dll getestet. Die hat so 3,5Mbyte

    Es gibt aber auch eine Datei vixd.dll - enthält die selben Aufrufe, ist aber 7 MByte groß. Mit der geht es ohne Absturz.

    Aber ... kommt noch besser. Wenn ich progandy's letzten Vorschlag nehme und die Aufrufe auf

    Zitat

    DllCall($dll, "INT:cdecl", "Funktion", ...


    ändere geht es auch mit der eigentlichen vix.dll

    Ändern musste ich ansonsten in der VixH.au3 das

    [autoit]

    Return $aRes[0]
    ; in
    Return $aRes

    [/autoit]


    da AutoIt meckerte das es kein Array sei.

    so, das lass ich jetzt mal so stehen bevor die nächste Frage gleich kommt :D

  • Wenn AutoIt meckert, dass es kein Array ist, dann gab es beim DLLCall einen Fehler.
    Die Änderung sollte so aussehen:

    [autoit]

    If @error Then Return SetError(1,@error,0)
    Return $aRes[0]

    [/autoit]
  • ich teste gerade Schritt für Schritt durch, DLL laden und die ersten beiden Funktionen klappt jetzt.
    Es muss ein DLLOpen erfolgen, sowie der Aufruf mit "INT:cdecl"

    durch den Rest hangel ich mich gerade Schritt für Schritt durch ....

    Ich habe aber immer noch nicht kapiert warum nach (aus dem C++ Beispiel)

    [autoit]

    err = VixJob_Wait(jobHandle,
    VIX_PROPERTY_JOB_RESULT_HANDLE,
    &hostHandle,
    VIX_PROPERTY_NONE);

    [/autoit]


    ein Zeiger in der &hostHandle stehen soll ... bei mir bleibt das ding leer .... (ist aber wichtig denn für die nächsten Funktionen brauche ich es immer)

  • Eine Möglichkeit ist das:

    Spoiler anzeigen
    [autoit]

    Func VixJob_Wait ($jobHandle, $v1, $v2 = 0 , $v3 = 0 , $v4 = 0 , $v5 = 0 , $v6 = 0 , $v7 = 0 , $v8 = 0 , $v9 = 0 , $v10 = 0 , $v11 = 0)
    If Mod(@NumParams , 2) Then Return SetError(1,0,0)
    If Eval("v" & (@NumParams-1)) <> 0 Then Return SetError(2,0,0)
    Local $aRes
    Switch @NumParams
    Case 2
    $aRes = DllCall ($vixdll, "UINT64:cdecl", "VixJob_Wait", "int", $jobHandle, "int", $v1)
    Case 4
    $aRes = DllCall ($vixdll, "UINT64:cdecl", "VixJob_Wait", "int", $jobHandle, "int", $v1, "ptr", $v2, "int", $v3)
    Case 6
    $aRes = DllCall ($vixdll, "UINT64:cdecl", "VixJob_Wait", "int", $jobHandle, "int", $v1, "ptr", $v2, "int", $v3, "ptr", $v4, "int", $v5)
    Case 8
    $aRes = DllCall ($vixdll, "UINT64:cdecl", "VixJob_Wait", "int", $jobHandle, "int", $v1, "ptr", $v2, "int", $v3, "ptr", $v4, "int", $v5, "ptr", $v6, "int", $v7)
    Case 10
    $aRes = DllCall ($vixdll, "UINT64:cdecl", "VixJob_Wait", "int", $jobHandle, "int", $v1, "ptr", $v2, "int", $v3, "ptr", $v4, "int", $v5, "ptr", $v6, "int", $v7, "ptr", $v8, "int", $v9)
    Case 12
    $aRes = DllCall ($vixdll, "UINT64:cdecl", "VixJob_Wait", "int", $jobHandle, "int", $v1, "ptr", $v2, "int", $v3, "ptr", $v4, "int", $v5, "ptr", $v6, "int", $v7, "ptr", $v8, "int", $v9, "ptr", $v10, "int", $v11)
    EndSwitch
    If @error Then Return SetError(3, @error, 0)
    Return $aRes[0]
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    $tHandle = DllStructCreate("int")
    VixJob_Wait ($jobHandle, $VIX_PROPERTY_JOB_RESULT_HANDLE, DllStructGetPtr($tHandle), $VIX_PROPERTY_NONE)
    $hostHandle = DllStructGetData($tHandle, 1)

    [/autoit]
  • War (wieder einmal) der goldrichtige Ansatz!

    Ich bin jetzt soweit, das ich mich mit einem ESX Host verbinden, eine VM auswählen und diese Einschalten kann :rock:

    Allerdings ist da doch noch einiges an ausklingeln dran. z.B. muss ich den Pfad zur VM statt mit
    "/vmfs/volumes/4de1641e-86b215c7-e956-000c294be7bf/Nostalgia/Nostalgia.vmx" mit "[ha-datacenter/datastore1] Nostalgia/Nostalgia.vmx" angeben ... usw. ...

    und meine VixH.au3 funktioniert im moment garnicht ?( ... da muss ich mal suchen was ich da nebenbei für einen Bug eingebaut habe ... (hab mir nur ersteinmal die relevanten Sachen in ein Script geholt)

    Ich "klingel" jetzt ersteinmal die ESX / ESXi relevanten Befehle nacheinander durch (kann ich am meisten mit Anfangen) ... und giesse das in eine praxistaugliche UDF ... die ich dann auch auf "Norm" bzw. AutoIt-Standard trimme ...

    So, nun aber erstmal ein dickes Danke an ... Greenhorn :thumbup: für die erste Umsetzung der VixH.au3 (das war schon 90% der Arbeit) und die ConsoleWriteArray() Funktion - die hilft bei der Fehlersuche doch enorm!
    Und ein großes Danke an progandy der die ganz entscheidenen Tipps gegeben hat.

    Wenn es recht ist würde ich dieses Thema noch ein paar Tage offen lassen falls ich noch weitere Probleme habe.

    (ich liebe dieses Forum :love: )

    BLinz

  • Aufgrund einer Nachfrage poste ich hier mal ein funktionierendes Beispiel.

    Es nutzt nur die vix.dll und startet eine VM auf einem ESXi Server:

    Spoiler anzeigen
    [autoit]

    #cs ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    AutoIt Version: 3.3.6.1
    Author: myName

    [/autoit] [autoit][/autoit] [autoit]

    Script Function:
    Template AutoIt script.

    [/autoit] [autoit][/autoit] [autoit]

    #ce ----------------------------------------------------------------------------

    [/autoit] [autoit][/autoit] [autoit]

    ; Script Start - Add your code below here

    [/autoit] [autoit][/autoit] [autoit]

    ;#include "VixH.au3"
    #include <Array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Dim $vixdll
    Dim $aRes1
    Dim $aRes2
    Dim $tHandle
    Dim $hostHandle
    Dim $vmHandle
    Dim $jobHandle
    Dim $err
    Global Enum $VIX_PROPERTY_JOB_RESULT_HANDLE = 3010
    Global Enum $VIX_PROPERTY_NONE = 0
    Global Enum $VIX_INVALID_HANDLE = 0
    Global Enum $VIX_VMPOWEROP_NORMAL = 0

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    Func ConsoleWriteArray (ByRef Const $array, $sArrayName = "")
    Local $cnColumns
    Local $cnDimension
    Local $cnRows
    Local $cnElements
    If (not IsArray ($array)) Then
    ConsoleWrite (StringFormat ("!--- ConsoleWriteArray - Fehler: %s ist kein Array!\n", $sArrayName))
    Return 0
    EndIf
    $cnDimension = UBound ($array, 0)
    If ($cnDimension > 3) Then
    ConsoleWrite (StringFormat ("!--- ConsoleWriteArray - Fehler: %d\n", $sArrayName, $cnDimension))
    ConsoleWrite (StringFormat ("!--- Max. Anzahl Dimensionen: %d\n", 3))
    ConsoleWrite (StringFormat ("!--- %s - Anzahl Dimensionen: %d\n", $sArrayName, $cnDimension))
    Return 0
    EndIf
    ConsoleWrite (StringFormat ("--- Arrayvariable %s\n--- Anzahl Dimensionen: %d\n", $sArrayName, $cnDimension))
    $cnRows = UBound ($array, 1)
    $cnColumns = UBound ($array, 2)
    $cnElements = UBound ($array, 3)
    Switch ($cnDimension)
    Case 1
    ;...
    ConsoleWrite (StringFormat ("--- Anzahl Elemente: %d\n", $cnRows))
    For $i = 0 To $cnRows - 1
    ConsoleWrite (StringFormat ("; %s [%d] = %s\n", $sArrayName, $i, $array[$i]))
    Next
    Case 2
    ;...
    ConsoleWrite (StringFormat ("--- Anzahl Elemente: %d\n", $cnRows))
    For $i = 0 To $cnRows - 1
    For $j = 0 To $cnColumns - 1
    ConsoleWrite (StringFormat ("; %s [%d][%d] = %s\n", $sArrayName, $i, $j, $array[$i][$j]))
    Next
    Next
    Case 3
    ;...
    ConsoleWrite (StringFormat ("--- Anzahl Elemente: %d\n", $cnRows))
    For $i = 0 To $cnRows - 1
    For $j = 0 To $cnColumns - 1
    For $k = 0 To $cnElements - 1
    ConsoleWrite (StringFormat ("; %s [%d][%d][%d] = %s\n", $sArrayName, $i, $j, $k, $array[$i][$j][$k]))
    Next
    Next
    Next
    Case Else
    ;...
    EndSwitch
    ConsoleWrite (StringFormat ("----------------------------\n\n", 0))
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func Vix_ReleaseHandle ($handle)

    [/autoit] [autoit][/autoit] [autoit]

    Local $aRes = DllCall ($vixdll, "none", "Vix_ReleaseHandle", _
    "int", $handle) ; VixHandle
    Return $aRes[0]

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func VixVM_Open ($hostHandle, $vmxFilePathName, $callbackProc, $clientData)

    [/autoit] [autoit][/autoit] [autoit]

    Local $aRes = DllCall ($vixdll, "INT:cdecl", "VixVM_Open", _
    "INT", $hostHandle, _
    "str", $vmxFilePathName, _
    "PTR", $callbackProc, _
    "PTR", $clientData)
    Return $aRes[0]
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func VixVM_PowerOn ($vmHandle, $powerOnOptions, $propertyListHandle, $callbackProc, $clientData)

    [/autoit] [autoit][/autoit] [autoit]

    Local $aRes = DllCall ($vixdll, "INT:cdecl", "VixVM_PowerOn", _
    "INT", $vmHandle, _
    "INT", $powerOnOptions, _
    "INT", $propertyListHandle, _
    "PTR", $callbackProc, _
    "PTR", $clientData)
    Return $aRes[0]
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func VixJob_Wait ($jobHandle, $v1, $v2 = 0 , $v3 = 0 , $v4 = 0 , $v5 = 0 , $v6 = 0 , $v7 = 0 , $v8 = 0 , $v9 = 0 , $v10 = 0 , $v11 = 0)
    ConsoleWrite("NumParams:" & @NumParams & @CRLF)
    ;If Mod(@NumParams , 2) Then Return SetError(1,0,0)
    ;If Eval("v" & (@NumParams-1)) <> 0 Then Return SetError(2,0,0)
    Local $aRes
    Switch @NumParams
    Case 2
    ConsoleWrite("Case 2")
    $aRes = DllCall ($vixdll, "UINT64:cdecl", "VixJob_Wait", "int", $jobHandle, "int", $v1)
    Case 4
    $aRes = DllCall ($vixdll, "UINT64:cdecl", "VixJob_Wait", "int", $jobHandle, "int", $v1, "ptr", $v2, "int", $v3)
    Case 6
    $aRes = DllCall ($vixdll, "UINT64:cdecl", "VixJob_Wait", "int", $jobHandle, "int", $v1, "ptr", $v2, "int", $v3, "ptr", $v4, "int", $v5)
    Case 8
    $aRes = DllCall ($vixdll, "UINT64:cdecl", "VixJob_Wait", "int", $jobHandle, "int", $v1, "ptr", $v2, "int", $v3, "ptr", $v4, "int", $v5, "ptr", $v6, "int", $v7)
    Case 10
    $aRes = DllCall ($vixdll, "UINT64:cdecl", "VixJob_Wait", "int", $jobHandle, "int", $v1, "ptr", $v2, "int", $v3, "ptr", $v4, "int", $v5, "ptr", $v6, "int", $v7, "ptr", $v8, "int", $v9)
    Case 12
    $aRes = DllCall ($vixdll, "UINT64:cdecl", "VixJob_Wait", "int", $jobHandle, "int", $v1, "ptr", $v2, "int", $v3, "ptr", $v4, "int", $v5, "ptr", $v6, "int", $v7, "ptr", $v8, "int", $v9, "ptr", $v10, "int", $v11)
    EndSwitch
    If @error Then Return SetError(3, @error, 0)
    Return $aRes[0]
    EndFunc

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;#####################################################################################################################################################################################
    ;#####################################################################################################################################################################################
    ;#####################################################################################################################################################################################
    ;#####################################################################################################################################################################################
    ;#####################################################################################################################################################################################

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;Global $MyhostHandle = $VIX_INVALID_HANDLE
    ;Dim $MyjobHandle = $VIX_INVALID_HANDLE
    ;Dim $MyERR

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    ;$vixdll = DllOpen ("vix.dll")
    ;If @error Then
    ; ConsoleWrite('Fehler beim Öffnen der DLL' & @CRLF)
    ; Exit
    ;EndIf
    ;ConsoleWrite ('"' & $vixdll & '"' & @CRLF)
    $vixdll = DllOpen("vix.dll")
    ConsoleWrite ($vixdll & "---" & @error & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    ;$aRes = DllCall ($vixdll, "INT", "VixHost_Connect", "INT", -1, "INT", 10, "str", "https://192.168.28.128/sdk", "INT", 443, "str", "root", "str", "test1234", "INT", 0, "INT", 0, "PTR", 0, "PTR", 0)
    $aRes1 = DllCall ($vixdll, "INT:cdecl", "VixHost_Connect", "INT", -1, "INT", 10, "str", "https://192.168.28.128/sdk", "INT", 443, "str", "root", "str", "test1234", "INT", 0, "INT", 0, "PTR", 0, "PTR", 0)
    ConsoleWrite("---" & @error & @CRLF)
    ConsoleWriteArray($aRes1)

    [/autoit] [autoit][/autoit] [autoit]

    $tHandle = DllStructCreate("int")
    $err = VixJob_Wait ($aRes1[0], $VIX_PROPERTY_JOB_RESULT_HANDLE, DllStructGetPtr($tHandle), $VIX_PROPERTY_NONE)
    $hostHandle = DllStructGetData($tHandle, 1)
    ConsoleWrite("---" & @error & "----" & $hostHandle & @CRLF)
    ConsoleWrite("$err =" & $err & @CRLF)
    ;ConsoleWriteArray($hostHandle)
    $aRes1 = 0
    $tHandle = 0
    $jobHandle = 0

    [/autoit] [autoit][/autoit] [autoit]

    $jobHandle = VixVM_Open ($hostHandle, "[ha-datacenter/datastore1] Nostalgia/Nostalgia.vmx", 0, 0)
    $tHandle = DllStructCreate("int")
    $err = VixJob_Wait ($jobHandle, $VIX_PROPERTY_JOB_RESULT_HANDLE, DllStructGetPtr($tHandle), $VIX_PROPERTY_NONE)
    $vmHandle = DllStructGetData($tHandle, 1)
    ConsoleWrite("---" & @error & "----" & $vmHandle & @CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    $tHandle = 0
    $jobHandle = 0

    [/autoit] [autoit][/autoit] [autoit]

    ;$jobHandle = VixVM_PowerOn ($vmHandle, $VIX_VMPOWEROP_NORMAL, $VIX_INVALID_HANDLE, 0, 0)
    $aRes2 = DllCall ($vixdll, "INT:cdecl", "VixVM_PowerOn", "INT", $vmHandle, "INT", 0, "INT", 0, "PTR", 0, "PTR", 0)
    ConsoleWriteArray($ares2)

    [/autoit] [autoit][/autoit] [autoit]

    $err = VixJob_Wait ($aRes2[0], $VIX_PROPERTY_NONE)
    ConsoleWrite("---" & @error & "----" & $err & @CRLF)

    [/autoit] [autoit][/autoit] [autoit][/autoit] [autoit]

    DllClose($vixdll)

    [/autoit]

    Hier nochmal als zip inklusive der "Vorbereiteten" VIXEasy.au3 mit allen Befehlen zum includen und der DLL selbst (funzt mindestens bis ESX 4.1 U1)

  • Hallo Blinz, danke für Deinen Code, mal sehen, wie ich ihn verwenden kann.

    Wenn ich weiter komme, halte ich Euch hier auf dem Laufenden.


    Gruß, Goink