Arbeiten mit BSTR

  • Hallo AutoIt'ler

    ich bin derzeit daran via COM Schnittstelle ein Softwaretool zu steuern.
    Dies funktioniert soweit auch wie ich mir das vorgestellt habe.
    Jedoch ist es mir nicht möglich die überlieferten Strings auszulesen.

    Die Dokumentation der Software beschreibt die Funktion folgendermaßen:

    Code
    GetVar([in] BSTR name, [out, retval] BSTR* value) liest eine Variable als Text zurück.

    Variablen die als BSTR übergeben werden kann ich ohne Probleme auslesen.

    [autoit]

    $val = $oObj.GetVar( "var" )

    [/autoit]

    Ich komme jedoch nicht an die Daten heran die in BSTR* geschrieben werden sollten.

    Ich habe bereits die Funktionen __IEStringToBstr und __IEBstrToString versucht, leider auch erfolglos. (1)
    Daher habe ich mir die Spezifikationen von BSTR angeschaut und folgendes versucht: (2 3)

    [autoit]

    Func StringToBstr( ByRef $vBSTRstorage, $sString )
    $dwSize = StringLen( $sString )
    $tBSTR = "DWORD dwSize; WCHAR wcStr["&$dwSize+1&"]"
    $vBSTRstorage = DllStructCreate( $tBSTR )

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

    DllStructSetData( $vBSTRstorage, "dwSize", $dwSize*2 )
    DllStructSetData( $vBSTRstorage, "wcStr", $sString )

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

    Return DllStructGetPtr($vBSTRstorage) +4
    EndFunc

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

    Func BstrToString( $pBSTR )
    $tBSTR = "DWORD dwSize"
    $data = DllStructCreate( $tBSTR, $pBSTR -4 )

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

    $dwSize = DllStructGetData( $data, "dwSize" ) /2
    $tBSTR = "DWORD dwSize; WCHAR wcStr["&$dwSize+1&"]"
    $data = DllStructCreate( $tBSTR, $pBSTR -4 )

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

    Return DllStructGetData( $data, "wcStr" )
    EndFunc

    [/autoit]

    Leider auch erfolglos!

    Kann mir jemand weiterhelfen?

    Einmal editiert, zuletzt von tromorow (23. September 2014 um 11:11)

  • Hallo funkey,

    danke, aber leider auch erfolglos.

    [autoit]

    $sBSTR = _SysAllocString("TEST")
    $val = $oObj.GetVar( "var", $sBSTR )
    $tTest = DllStructCreate("wchar[6]", $sBSTR)
    ConsoleWrite( "$oObj.GetVar: " & DllStructGetData($tTest, 1) & @CRLF) ; RES: "$oObj.GetVar: TEST"
    _SysFreeString($sBSTR)

    [/autoit]

    weitere Vorschläge/Ideen?

  • Hast du es mit einem normalen AutoIt- String auch versucht?
    Um welche Software handelt es sich. Könnte ich die auch installieren zum testen? Ansonsten ist guter Rat teuer. Ich weiß nur, dass noch lange nicht alles was COM betrifft mit AutoIt auch funktioniert, leider! Hab mich auch schon des öfteren geärgert.

  • Ja, habe es bereits mit Autoit-Strings versucht.

    Es handelt sich um die Berechnungssoftware KISSsoft.
    Ich weiß nicht in wie weit die Demoversion benutzbar ist.
    Aber du kannst es theoretisch mit GetININame versuchen.

    Hier ein Beispiel:

    [autoit]

    $hKissSoft = ObjCreate( "KISSsoftCOM.KISSsoft" )
    If @error Then
    MsgBox( 0+48, "ERROR", "Failed to open KISSsoft!" )
    Exit
    EndIf

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

    ;$hKissSoft.SetSilentMode( True )
    $hKissSoft.GetModule( "Z012", True )

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

    $sTest = "TEST"
    $val = $hKissSoft.GetININame( $sTest )
    ConsoleWrite( "> GetININame: "&$sTest&@CRLF )

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

    $hKissSoft.ReleaseModule

    [/autoit]
  • Hab mal die Demo-Version installiert, danach gesucht wie ich den COM-Server registrieren kann, dann getestet, dann zu folgendem Ergebnis gekommen:

    Spoiler anzeigen
    [autoit]


    Global $oErrorHandler = ObjEvent("AutoIt.Error", "_ErrFunc")

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

    Global $oKissSoft = ObjCreate("KISSsoftCOM.KISSsoft")
    If @error Then
    MsgBox(0 + 48, "ERROR", "Failed to open KISSsoft!")
    Exit
    EndIf

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

    ;$oKissSoft.SetSilentMode( True )
    $oKissSoft.GetModule("Z012", True)

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

    Global $sIni = $oKissSoft.GetININame()
    ConsoleWrite("> GetININame: " & $sIni & @CRLF)

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

    Global $sVar = $oKissSoft.GetVar("var")
    ConsoleWrite("> Var: " & $sVar & @CRLF)

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

    $oKissSoft.ReleaseModule

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

    ; User's COM error function. Will be called if COM error occurs
    Func _ErrFunc($oError)
    ; Do anything here.
    ConsoleWrite("err.number is: " & @TAB & "0x" & Hex($oError.number, 8) & @CRLF & _
    "err.windescription:" & @TAB & $oError.windescription & @CRLF & _
    "err.description is: " & @TAB & $oError.description & @CRLF & _
    "err.source is: " & @TAB & $oError.source & @CRLF & _
    "err.helpfile is: " & @TAB & $oError.helpfile & @CRLF & _
    "err.helpcontext is: " & @TAB & $oError.helpcontext & @CRLF & _
    "err.lastdllerror is: " & @TAB & $oError.lastdllerror & @CRLF & _
    "err.scriptline is: " & @TAB & $oError.scriptline & @CRLF & _
    "err.retcode is: " & @TAB & $oError.retcode & @CRLF & @CRLF)
    EndFunc ;==>_ErrFunc

    [/autoit]


    Bei mir bringt das zwar Fehlermeldungen, aber bei dir dürfte es funktionieren.

    Edit:
    Hier noch die COM-Schnittstelle, wie sie im PowerBasic COM-Browser dargestellt wird. Da sieht man auch wie die Funktionen in AutoIt aufgerufen werden müssen ;)

    Spoiler anzeigen
  • Oh sch....,

    auf die Idee bin ich bisher noch nicht gekommen. :S
    Vielen Dank!
    Dann scheinen die Variablen, welche ich bisher auslesen wollte keinen Wert zu haben.

    Damit sollte ich weiter kommen! :)
    Vielen Dank funkey!