Aufruf von externen dll's aus Script

  • Hallo zusammen,


    ich habe mal wieder ein Problem das ich überhaupt nicht kapiere und muss dazu etwas weiter ausholen.


    Vor einigen Jahren habe ich in den PostOpen jeder Maildatenbank ein Script eingebaut das mir einmal am Tag, beim ersten öffnen der Mail-DB Informationen über den Client in eine Mail-In DB sendet. Und zwar: Maschinenname, IP-Adresse, Betriebssystem-Version und Notes-Client Version.
    Damals haben wir das gebraucht um vor dem Rollout von Win-XP und Notes 6 erstmal einen Überblick zu bekommen wer überhaupt welche Versionen installiert hat.
    Heute ist es immer noch sehr nützlich um schnell die IP-Adresse zu bekommen um mich dann per Fernsteuerung im Supportfall aufzuschalten.


    Den Code habe ich über irgendein Forum gefunden und ihn, ehrlich gesagt, übernommen ohne ihn wirklich zu verstehen.


    In den Declarations des Datenbank-Script ist folgender Code:


    Private Type OSVERSIONINFO
    dwOSVersionInfoSize As Long
    dwMajorVersion As Long
    dwMinorVersion As Long
    dwBuildNumber As Long
    dwPlatformId As Long
    szCSDVersion As String * 128
    End Type


    Type HOSTENT
    hName As Long
    hAliases As Long
    hAddrType As Integer
    hLen As Integer
    hAddrList As Long
    End Type


    Declare Private Function GetVersionEx Lib "kernel32" Alias "GetVersionExA" (lpVersionInformation As OSVERSIONINFO) As Long


    Declare Function gethostname Lib "WSOCK32.DLL" (Byval szHost As String, Byval dwHostLen As Long) As Long


    Declare Function gethostbyname Lib "WSOCK32.DLL" (Byval szHost As String) As Long


    Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, Byval hpvSource As Long, Byval cbCopy As Long)


    Verwendet werden diese Deklarationen dann in folgendem Code:
    Function GetIP() As String
    Dim HostName As String * 256
    Dim HostPointer As Long
    Dim HostStruct As HOSTENT
    Dim HostAddressPointer As Long
    Dim HostAddress As Long
    Dim AddressNum As String
    Dim Address As String

    gethostname HostName, 256
    HostName = Trim(HostName)
    HostPointer = gethostbyname(HostName)

    CopyMemory HostStruct, HostPointer, Len(HostStruct)
    CopyMemory HostAddressPointer, HostStruct.hAddrList, 4
    CopyMemory HostAddress, HostAddressPointer, 4

    AddressNum = Trim(Hex(HostAddress))
    AddressNum = String(8-Len(AddressNum), Asc("0")) & AddressNum

    Address = Cstr(Cint("&H" & Mid(AddressNum, 7))) & "." & Cstr(Cint("&H" & Mid(AddressNum, 5, 2))) & "." & Cstr(Cint("&H" & Mid(AddressNum, 3, 2))) & "." & Cstr(Cint("&H" & Left(AddressNum, 2)))

    GetIP = Address
    End Function


    Function GetMachineName() As String
    Dim HostName As String * 256
    Dim HostName2 As String
    Dim counter As Integer

    gethostname HostName, 256
    HostName = Trim(HostName)

    counter = Instr(HostName, Chr(0))
    Hostname2 = Left$(HostName, counter-1)
    GetMachineName = HostName2
    End Function



    Function GetOSInfo() As String
    'Deklarationen
    Dim osinfo As OSVERSIONINFO
    Dim counter As Integer
    Dim losinfo As Long
    Dim osys As String
    Dim spack As String
    'Startwerte setzen
    osinfo.dwOSVersionInfoSize = 148
    'Version auslesen
    losinfo = GetVersionEx(osinfo)
    'Daten auswerten
    Select Case osinfo.dwMajorVersion
    Case 3
    Select Case osinfo.dwMinorVersion
    Case 51
    osys = "Windows NT 3.51"
    Case Else
    osys = "Unbekanntes Betriebssystem"
    End Select
    Case 4
    Select Case osinfo.dwMinorVersion
    Case 0
    If osinfo.dwPlatformID = 2 Then
    osys = "Windows NT 4.0"
    Else
    osys = "Windows 95"
    End If
    Case 10
    osys = "Windows 98"
    Case 90
    osys = "Windows Me"
    Case Else
    osys = "Unbekanntes Betriebssystem"
    End Select
    Case 5
    Select Case osinfo.dwMinorVersion
    Case 0
    osys = "Windows 2000"
    Case 1
    osys = "Windows XP"
    Case 2
    osys = "Windows Server 2003"
    Case Else
    osys = "Unbekanntes Betriebssystem"
    End Select
    End Select
    counter = Instr(osinfo.szCSDVersion, Chr(0))
    spack = Left$(osinfo.szCSDVersion, counter-1)
    If spack = "" Then
    GetOSInfo = osys
    Else
    GetOSInfo = osys + " - " + spack
    End If

    End Function


    Das Ganze wurde eingebaut in die 6er Mailschablone und funktioniert seit Jahren einwandfrei.
    Mittlerweile habe ich, und viele Andere auch, die Client-Version 7.0.2. Also hab ich mich drangemacht unsere Anpassungen auf die 7er Schablone zu portieren.


    Anschließend die Schablone meiner Maildatenbank auf die neue 7er gewechselt und siehe da: Beim Aufruf der CopyMemory Funktion bekomme ich die Fehlermeldung "Cannot find external name: **einige Sonderzeichen**"
    Anschließend stellt der Notes-Client jede Funktion ein und lässt sich nur noch per ZapNotes beenden.


    Zurückgewechselt auf die 6er Schablone läuft wieder alles einwandfrei.


    Dann habe ich wieder auf die 7er Gestaltung gewechselt, alle Scripte neu kompiliert woraufhin sich die Fehlermeldung ein wenig geändert hat: "Cannot find external name: $ $DBSCRIPT"
    Abstürzen tut er allerdings weiterhin.


    Der Client ist in beiden Fällen der Selbe. Der Code ist absolut identisch.
    Fällt irgendjemandem eine Erklärung dafür ein?
    :-?

  • Passiert das ganze auch wenn du das Database Script in einer Datenbank mit dem 6er Design neu speicherst ?


    Wenn ja dann liegt es einfach an der Berechtigung deines Users in der ECL


    Cannot find external name tritt unter anderem auch dann auf, wenn man versucht auf eine API Funktion zuzugreifen, dies aber wegen ECL Einstellungen nicht darf.


    Und wenn das Database Script deiner 6er Schablone mit einem anderen User unterzeichnet ist, der das darf und die 7er das nicht ist, logischerweise weil du es ja geändert hast, dann kommt es dazu

  • Vielen Dank für deine Anregungen!


    Zunächst einmal zu den Rechten: Es gibt in unserer Firma niemanden der mehr Rechte (in Notes :D ) hat als ich.
    Fast jeder Code ist mit meiner ID signiert und die Signatur ist in allen ECL's drin. ECL kann es eigentlich nicht sein, da diese soweit ich weiß auf den lokalen Client bezogen arbeitet, und nicht auf die Datenbank.


    Ich habe dann mal angefangen rumzuexperimentieren wie sich der Code in anderen Datenbanken verhält.
    Zuerst mal habe ich eine ältere Testanwendung, noch mit ODS 41, genommen, den Code dort eingebaut und getestet.
    --> läuft


    Dann eine komplett neue, leere DB angelegt, Code eingebaut
    --> läuft


    Dann aus der 7er Schablone den Code wieder rausgenommen und alles Script neu kompiliert. Über die Mail-DB drübergebügelt und alles ist normal gelaufen.
    Dann wieder den Code in die Schablone rein und Design-Update gemacht
    --> Peng


    Morgen probier ich mal aus was passiert wenn ich den Code in die extended Mail Schablone einbaue.

  • Da wir in unserer Mailschablone noch eine Reihe von Anpassungen drin haben habe ich jetzt zum Testen eine Originalschablone genommen.


    Zuerst die normale mail7.ntf. Code eingebaut --> Peng
    Dann die mail7ex.ntf mit gleichem Ergebnis.


    Die entsprechenden 6er Schablonen funktionieren hingegen einwandfrei.


    Irgendetwas muss in den 7er Schablonen drin sein ???

  • Ja, im Postopen.


    Der Code ist ganz einfach:
    'Tägliches sammeln von Systeminformationen
    'Erstmal das Tagesdatum bestimmen wegen dem Timestamp
    Set thisday = New NotesDateTime(Today)
    'Dann prüfen ob das Script heute schonmal gelaufen ist
    If CheckRunCondition("DailySysInfo", thisday.DateOnly) Then Exit Sub
    'Systeminformationen sammeln
    ipadr = GetIP
    hostname = GetMachineName
    osversion = GetOSInfo
    notesversion = session.NotesVersion
    counter = Instr(notesversion,"|")
    If Not counter = 0 Then notesversion = Left$(notesversion,counter-1)
    notesbuild = session.NotesBuildVersion
    'String zum versenden zusammenstellen
    parsestr = hostname+"~"+ipadr+"~"+osversion+"~"+notesversion+"~"+notesbuild+"~"+thisday.DateOnly
    'Versand einer Mail mit den erhobenen Daten
    Set db = session.CurrentDatabase
    Set message = db.CreateDocument
    message.Form = "Memo"
    message.Subject = "SysInfo " + thisday.DateOnly
    message.SendTo = "Inventory@myDomain"
    message.Principal = session.UserName
    Set rtitem = New NotesRichTextItem(message, "Body")
    Call rtitem.AppendText(parsestr)
    Call message.Send(False)
    'Flag setzen dass das Script heute schon gelaufen ist
    Call session.SetEnvironmentVar("DailySysInfo",thisday.DateOnly)

  • Hallo zusammen,


    zum Zwecke der Dokumentation und falls es jemanden interessiert hier die Lösung meines Problems:


    Auslöser war die folgende Zeile in den Declarations des Datenbank-Scripts:
    Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, Byval hpvSource As Long, Byval cbCopy As Long)


    Dazu muss man bemerken, dass dieser Code Jahrelang, in 5er und 6er Mailschablonen, unabhängig von der Client Version funktioniert hat.


    Heute habe ich nochmal bei IBM Developer Works gesucht und dabei in der Support Datenbank einen Beitrag gefunden in dem exakt der von mir verwendete Code zum Herausfinden der IP-Adresse eines Rechners vorgestellt wurde.
    Mit einer klitzekleinen Abweichung:
    Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (hpvDest As Any, Byval hpvSource As [size=large][color=FF0099]Any[/size][/color], Byval cbCopy As Long)


    Die Änderung des Datentyps von "Long" nach "Any" habe ich übernommen und jetzt läufts. :strike:


    Aber warum der alte Code überall läuft nur in der 7er Mailschablone nicht, wird wohl auf ewig im Dunkeln bleiben.