Problem mit DLL, zur Laufzeit laden...

  • VB.NET
  • .NET (FX) 1.0–2.0

Es gibt 10 Antworten in diesem Thema. Der letzte Beitrag () ist von exc-jdbi.

    Problem mit DLL, zur Laufzeit laden...

    Moin! :)
    Ich habe jetzt Stundenlang gegoogelt, leider ohne Erfolg!
    Ich möchte gerne eine DLL-Datei wärend der Laufzeit einbinden.
    Leider weiß ich nicht, genau wie ich dies erklären kann.
    Es gibt eine Sub mit dem Name „DLL_Aufruf(path,"name").
    Mein Ziel ist es das ich folgenden Code verwenden kann.
    _class.test() ' <---- hier test als name!
    Freue mich auf eure Hilfe.
    BIG THX

    VB.NET-Quellcode

    1. Const fullpath As String = "C:\Users\Cheffboss\Documents\Visual Studio 2010\Projects\TempNeu\ClassLibrary1\bin\Debug\ClassLibrary1.dll"
    2. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    3. DLL_Aufruf(fullpath, "test")
    4. End Sub
    5. Sub DLL_Aufruf(fullpath As String, name As Object)
    6. If Not System.IO.File.Exists(fullpath) Then Exit Sub
    7. Dim Assembly As Reflection.Assembly = Reflection.Assembly.LoadFile(fullpath)
    8. Dim _class As Object = Activator.CreateInstance(Assembly.GetType("ClassLibrary1.Class1"))
    9. _class.test() ' <---- hier test als name!
    10. End Sub


    VB.NET-Quellcode

    1. Public Class Class1
    2. Sub test()
    3. MsgBox("test")
    4. End Sub
    5. Public Sub test1()
    6. MsgBox("test1")
    7. End Sub
    8. End Class
    Visual Basic.NET 8o
    MS-SQL
    8o
    Hallo CheffBoss,

    möglicherweise hilft es, wenn du "ClassLibrary1" beim Typ wegläßt.
    Die ist ja durch die Assembly schon definiert.

    hier zwei hilfreiche Artikel:
    stackoverflow.com/questions/46…-type-knowing-only-the-na
    codeproject.com/articles/59739…g-assemblies-using-assemb

    Viel Spass
    Mandy
    Wenn du mich schon mit einem Hinweis auf Google IxQuick abspeisen willst...
    So schreib mir doch wenigstens die Suchbegriffe dazu :thumbup:
    Die Assembly wird korrekt geladen?
    Dann kannst du dir mal alle Typen die darin deklariert sind auslesen.

    Und schau dir die Beschreibung zu CreateInstance(...) nochmals an, da gibt es mehrere Varianten davon.
    Wenn du mich schon mit einem Hinweis auf Google IxQuick abspeisen willst...
    So schreib mir doch wenigstens die Suchbegriffe dazu :thumbup:
    @Cheffboss Dein Part sieht doch aus wie CodeDom-Handling.
    Ohne das jetzt getestet zu haben sollte so was zum Ziel führen:

    VB.NET-Quellcode

    1. Dim Assembly As System.Reflection.Assembly = System.Reflection.Assembly.LoadFile(fullpath)
    2. Dim methInfo As MethodInfo = Assembly.GetType("ClassLibrary1.Class1").GetMethod("test")
    3. Dim o As Object = methInfo.Invoke(Nothing, Nothing) ' hier müssten dann ggf. die Parameter rein
    Natürlich musst Du die Resultate auf Nothing testen und dann abbrechen.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Du machst ein Interface welche deine klasse Class1 implementiert und die aufrufbaren/zugreifbaren Member enthält. Die Assembly, die dieses Interface enthält referenzierst du in deiner Anwendung, die Class1-test() aufrufen soll ebenso, wie in der externen Assembly, die deine Class1 enthält.

    VB.NET-Quellcode

    1. Sub DLL_Aufruf(fullpath As String, name As Object)
    2. If Not System.IO.File.Exists(fullpath) Then Exit Sub
    3. Dim Assembly As Reflection.Assembly = Reflection.Assembly.LoadFile(fullpath)
    4. Dim _class As IBla = TryCast(Activator.CreateInstance(Assembly.GetType("ClassLibrary1.Class1")),IBla
    5. _class.test() ' <---- hier test als name!
    6. End Sub


    Also eher so wie in @Mandy 's erstem Link beschrieben.

    Solltest du es auf statische Methoden brauchen, oder willst es so wie @RodFromGermany machen und du brauchst den Aufruf mehrmals, dann orientier dich hier:
    stackoverflow.com/questions/29…-from-a-methodinfo-object

    In C# gibt es dann sogar noch die Möglichkeit das dynamic-keyword zu verwenden, was es meines Wissens in VB.Net nicht gibt. Dafür gibt es Option Strict Off(-.-). Ich mag beides nicht, dynamic ergibt natürlich mehr Sinn, da es expliziter ist und nicht einfach alles(und dann auch noch im kompletten File) zulässt. Jedoch gibt es kaum Gründe eines von beidem zu verwenden.
    Ich wollte auch mal ne total überflüssige Signatur:
    ---Leer---
    Wenn es sich um mehrere Assemblies handelt könnte man gleich von Anfang an festhalten, welche Klassen in den entsprechenden Assemblies vorhanden sind. Diese Infos in serialisierte Dateien oder in eine Liste abspeichern.

    Enthält einer der Assamblies eine bestimmte Methode kann sie instanziert werden und die entsprechenden Methoden wie unten dargestellt genutzt werden .

    Eine sicher sehr gute Lösung wäre der Weg über ein Interface wenn wirklich gute OOP-Kenntnisse vorhanden sind.

    Freundliche Grüsse

    exc-jdbi

    VB.NET-Quellcode

    1. Dim app As Assembly = Assembly.LoadFile(path)
    2. objCr = app.CreateInstance(config(0).Type, True)
    3. Dim ci As ConstructorInfo = objCr.GetType.GetConstructor(System.Type.EmptyTypes)
    4. Dim mi() As MethodInfo = ci.Invoke(Nothing).GetType.GetMethods
    5. methodes = New MethodInfo(sMethodes.Length - 1) {}
    6. For i As Integer = 0 To sMethodes.Length - 1
    7. For Each meth As MethodInfo In mi
    8. If meth.Name = sMethodes(i) Then
    9. methodes(i) = meth
    10. Exit For
    11. End If
    12. Next
    13. Next


    Und Aufrufen kann man die entsprechende Methode in der Assambly so

    VB.NET-Quellcode

    1. Dim res As T = CType(methodes(0).Invoke(objCr, New Object() {PARAMETER}), T)
    @anAlle

    Vielen Dank! :)
    Ich könnte das Problem nun lösen.
    Ich habe einfach eine neue Klasse erstellt,
    diese auf die DLL-Datei verweist.

    Hier der Beispielcode:

    VB.NET-Quellcode

    1. Public Class Form1
    2. Dim DLLPlugin As New Class1
    3. Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    4. DLLPlugin.HalloWelt()
    5. End Sub
    6. End Class


    VB.NET-Quellcode

    1. Public Class Class1
    2. Const fullpath As String = _
    3. "C:\Users\Cheffboss\Documents\Visual Studio 2010\Projects\TempNeu\ClassLibrary1\bin\Debug\ClassLibrary1.dll"
    4. Public Sub HalloWelt()
    5. Dim Assembly As Reflection.Assembly = Reflection.Assembly.LoadFile(fullpath)
    6. Dim _class As Object = Activator.CreateInstance(Assembly.GetType("ClassLibrary1.Class1"))
    7. _class.HalloWelt() ' <---- hier! (in der DLL, wird damit weiter gearbeitet...)
    8. End Sub
    9. End Class
    Visual Basic.NET 8o
    MS-SQL
    8o
    Versuch es mal so, eventuell geht das, wenn es sich um eine ganz normale Sub handelt ohne Parameterübergabe

    GetMethods()(0) müsste entsprechend angepasst werden mit, 0 oder 1,2,3 ... je nachdem welche Funktion du ansprechen willst.

    VB.NET-Quellcode

    1. _class.GetType().GetMethods()(0).Invoke(_class, Nothing)


    Sofern es sich um eine Sub oder Function mit Parameterübergabe müsst es anders behandelt werden.

    Freundliche Grüsse

    exc-jdbi