Einbinden eines Events aus einer Dll

  • VB.NET

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von Alex74.

    Einbinden eines Events aus einer Dll

    Hallo,

    Ich habe mehrere Dlls vorliegen die ich dynamisch ins programm einbinde.
    In der Dll befindet ist ein Event definiert welches sporadisch abgefeuert wird. dieses Event möchte ich nun in meinem Program abfragen.

    Ein einfaches Bsp. wie folgt

    Form1

    VB.NET-Quellcode

    1. Private Sub GetToolsFromDll(Directory As String)
    2. Dim ToolList As List(Of DllMember) = LoadDynamicDll(Directory, True) ' WIr laden die DLL's
    3. ToolsToolStripMenuItem.Visible = ToolList.Count > 0 ' Wir passen das Menu an
    4. DummyToolStripMenuItem.Visible = ToolList.Count = 0 ' Wir passen das Menu an
    5. For Each Item As DllMember In ToolList ' Wir durchlaufen die DLL's
    6. Dim NewItem As New ToolStripMenuItem(Item.Title) With {.Tag = Item, .Name = Item.Title} 'Wir erstellen ein MenuItem
    7. ToolsToolStripMenuItem.DropDownItems.Add(NewItem) 'WIr weisen es dem Menu zu
    8. AddHandler NewItem.Click, AddressOf Tool_Click 'WIr definieren einen Ereignishandler
    9. 'Dim e As Reflection.EventInfo = Item.myCls.GetType.GetEvent("FormChanged")
    10. NewItem = Nothing
    11. Next
    12. End Sub
    13. Private Sub Tool_Click(Sender As Object, e As EventArgs)
    14. Dim Member As DllMember = DirectCast(DirectCast(Sender, ToolStripMenuItem).Tag, DllMember)
    15. Dim myobj As Object = Member.MyMethode.Invoke(Member.myCls, Nothing)
    16. 'Dim svalue As Boolean = Member.myCls.GetType.GetMethod("IsRunning").Invoke(Member.myCls, Nothing) -> Aufruf Function In DLL
    17. End Sub


    Das Modul wo die Dll geladen wird schaut wie folgt aus

    VB.NET-Quellcode

    1. Private Function FoundDll(ByVal Directory As String, IncludeSubDirectorys As Boolean) As List(Of String)
    2. Dim FoundFiles As New List(Of String)
    3. Dim [Option] As IO.SearchOption = IIf(IncludeSubDirectorys, IO.SearchOption.AllDirectories, IO.SearchOption.TopDirectoryOnly)
    4. Dim oDir As New System.IO.DirectoryInfo(Directory)
    5. Dim oFile As System.IO.FileInfo() = oDir.GetFiles("*.dll", [Option])
    6. For Each Item As IO.FileInfo In oFile : FoundFiles.Add(Item.FullName) : Next
    7. Return FoundFiles
    8. End Function
    9. Public Function LoadDynamicDll(ByVal Directory As String, ByVal IncludeSubDirectorys As Boolean) As List(Of DllMember)
    10. Dim Member As New List(Of DllMember)
    11. Dim NewMember As DllMember
    12. Dim DllList As List(Of String) = FoundDll(Directory, IncludeSubDirectorys)
    13. If DllList.Count = 0 Then Return Member
    14. For Each Item As String In DllList
    15. NewMember = RunDll(Item)
    16. If Not IsNothing(NewMember) Then Member.Add(NewMember)
    17. Next
    18. Return Member
    19. 'Member(0).MyMethode.Invoke(Member(0).myCls, Nothing) -> So kann aus der Klasse das Tool gestartet werden...
    20. End Function
    21. Private Function RunDll(sFile As String) As DllMember
    22. Try
    23. Dim assembly As Reflection.Assembly
    24. Dim myMethode As Reflection.MethodInfo
    25. Dim myCls As Object
    26. assembly = Reflection.Assembly.LoadFile(sFile)
    27. If IsNothing(assembly) Then Return Nothing
    28. myCls = assembly.CreateInstance(assembly.ExportedTypes(0).FullName)
    29. If IsNothing(myCls) Then Return Nothing
    30. myMethode = myCls.GetType.GetMethod("Run")
    31. If IsNothing(myMethode) Then Return Nothing
    32. Return New DllMember(myCls, myMethode, assembly.ExportedTypes(1).Namespace.ToString)
    33. 'myMethode.Invoke(myCls, Nothing) -> So wird die Dll gestartet....
    34. Catch ex As Exception
    35. Return Nothing '-> Kann auftreten, wenn im Modul kein Manifest vorliegt, falsche dll zum bsp.
    36. End Try
    37. End Function


    Und die dazugehörige Klasse

    VB.NET-Quellcode

    1. Public Property myCls As Object
    2. Public Property MyMethode As Reflection.MethodInfo
    3. Public Property Title As String
    4. Public Sub New(MyCls As Object, Methode As Reflection.MethodInfo, Bezeichner As String)
    5. Me.myCls = MyCls
    6. Me.MyMethode = Methode
    7. Me.Title = Bezeichner.Replace("_", " ")
    8. End Sub


    Ein simples Bsp. wie die Dll ausschaut ist wie folgt

    VB.NET-Quellcode

    1. Public Event FormChanged(ByVal Status As Boolean)
    2. Public Sub Run()
    3. Dim myfrm As New frmIpList(Me)
    4. myfrm.Show()
    5. IsRunning(True)
    6. End Sub
    7. Public Sub IsRunning(sValue As Boolean)
    8. RaiseEvent FormChanged(sValue)
    9. End Sub


    In der Form( in der Dll) wird lediglich beim drücken des Beenden Buttons die Form geschlossen und IsRunning auf False gesetzt und somit das Event ausgelöst.

    Meine Frage wäre jetzt wie kann ich das Event im Program abfragen?

    LG ALex

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Alex74“ ()

    Du postest sehr viel irrelevanten Code. Warum?
    Die Methode IsRunning feuert kein Event! Schau sie Dir nochmal genau an!
    Der letzte Codeblock ist aus der betroffenen Klasse herausgerissen, es ist nicht erkenntlich, wozu dieser Code gehört.
    Grundsätzlich ist es so wie in Codeblock#1, Zeile#8: AddHandler DasEventfeuerndeObjekt.DasEvent, AddressOf DeinEventHandler
    Wenn das Objekt nicht dynamisch erzeugt wird, sondern zu Programmstart feststeht, kann man auch mit der Handles-Klausel arbeiten.
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Hallo VasporiZed,

    erst einmal Danke für Deine Antwort.

    Ich habe den für mich relevanten Teil aus dem Program gepostet, damit man erkennen kann, wo und wie die DLL dynamisch geladen werden.
    Da diese Daten in einer Klasse vorliegen, so habe ich auch den Teil gepostet, wo man sieht wo ich wie auf die dll dann darauf zugreife.
    Der Code im Letzten Block, ist ein kleiner Ausschnitt aus der DLL. Deswegen war es ein wenig viel Code was ich gepostet hatte.

    Wieso die Methode IsRunning das Event nicht abfeuert kann ich so nicht erkennen und mir fällt adhockl auch nicht ein was daran falsch sein sollte. Aber um dies zu testen komme ich nicht dazu, weil ich ja eben nicht weiss, wie ich den AddHandler im Formular schreiben soll, da die dll's ja dynamisch geladen werden.

    Und genau das ist halt mein Problem wo ich derzeit nicht weiterkomme.

    LG Alex

    Alex74 schrieb:

    Wieso die Methode IsRunning das Event nicht abfeuert kann ich so nicht erkennen und mir fällt adhockl auch nicht ein was daran falsch sein sollte.
    Veralbern kann ich mich selbst. Ich hab meinen Post 9:25 geschickt und Du hast Deinen 9:33 geändert, und zwar von

    VB.NET-Quellcode

    1. Public Function IsRunning() As Boolean
    2. Return isRun
    3. RaiseEvent FormChanged(isRun)
    4. End Function

    zu

    VB.NET-Quellcode

    1. Public Sub IsRunning(sValue As Boolean)
    2. RaiseEvent FormChanged(sValue)
    3. End Sub
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    @Alex74 Wo hast Du das Event FormChanged abonniert?
    Poste den relevanten Code.
    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!
    @VaporiZed

    das war nicht meine Absicht gewesen. Ich hatte den Sourcecode eingestellt und wie ich Ihn mir nochmal durchgelesen habe, habe ich den Fehler selbst erkannt. Hab ihn dann behoben und das Posting entsprechend geändert. Ich bin davon ausgegangen das der Beitrag nicht so schnell gelesen wird und man nur die Änderung sieht.

    @RodFromGermany

    genau da liegt mein Problem. Ich weiss nicht wie ich das Abo eintragen muss
    Würde es in diese Routine mit reinschreiben

    VB.NET-Quellcode

    1. Private Sub GetToolsFromDll(Directory As String)
    2. Dim ToolList As List(Of DllMember) = LoadDynamicDll(Directory, True) ' WIr laden die DLL's
    3. ToolsToolStripMenuItem.Visible = ToolList.Count > 0 ' Wir passen das Menu an
    4. DummyToolStripMenuItem.Visible = ToolList.Count = 0 ' Wir passen das Menu an
    5. For Each Item As DllMember In ToolList ' Wir durchlaufen die DLL's
    6. Dim NewItem As New ToolStripMenuItem(Item.Title) With {.Tag = Item, .Name = Item.Title} 'Wir erstellen ein MenuItem
    7. ToolsToolStripMenuItem.DropDownItems.Add(NewItem) 'WIr weisen es dem Menu zu
    8. AddHandler NewItem.Click, AddressOf Tool_Click 'WIr definieren einen Ereignishandler
    9. ' Hier jetzt Event abonnieren
    10. NewItem = Nothing
    11. Next
    12. End Sub


    LG Alex
    @Alex74 Lade die DLLs über ein Interface, das Du instanziieren lässt, das kann Events haben, die Du abonnieren kannst.
    Suche im Forum nach Plugin, Plugin-System.
    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!