Funktion eines Plugins aufrufen schlägt fehl

  • VB.NET

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

    Funktion eines Plugins aufrufen schlägt fehl

    Hallo,

    ich probiere im Moment ein Pluginsystem in mein Programm einzubauen. In den Plugins ist jeweils eine Funktion um ein Bitmap zu zeichnen und zurückzugeben. Ich kann das Plugin laden und aufrufen. Bei einem "Clock" Plugin bekomme ich nix zurück, bei einem "Systemmonitor" bekomme ich ein Fehler zurück, womit ich aber nichts anfangen kann.

    VB.NET-Quellcode

    1. Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
    2. Debug.Print(NUM.ToString)
    3. Dim plug As String = availablePlugins(NUM - 1)
    4. Dim asm As Assembly = Assembly.LoadFrom(plug)
    5. Dim myType As System.Type = asm.GetType(asm.GetName.Name + ".Plugin")
    6. Dim plugin As LPlugin = CType(Activator.CreateInstance(myType), LPlugin)
    7. bmp = plugin.ShowLCD(bmp, AppNUM)
    8. BitmapToBLCD(bmp)
    9. End Sub

    So rufe ich in einem 1-Sekunden Timer die jeweilige Funktion auf.
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Public Function ShowLCD(ByVal _bmp As System.Drawing.Bitmap, ByVal _NUM As Integer) As Bitmap Implements LCDAPI.LPlugin.ShowLCD
    2. Dim DIGIT As Font = New Font("Quartz MS", 20)
    3. Dim fnt As Font = New Font("Courier New", 8)
    4. ' Grafikbereich bereitstellen
    5. Dim g As System.Drawing.Graphics = Graphics.FromImage(_bmp)
    6. 'Grafikfläche bereinigen
    7. Dim clearall As New Rectangle(0, 0, 128, 64)
    8. Dim clearallbrush As New LinearGradientBrush(clearall, Color.White, Color.White, LinearGradientMode.Horizontal)
    9. g.FillRectangle(clearallbrush, clearall)
    10. ' Textrenderer herunterschrauben (Keine Graustufen)
    11. g.TextRenderingHint = Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit
    12. If _NUM = 1 Then
    13. ' ---Digitaluhr
    14. ' Ein "Weisses Rechteck" definieren
    15. Dim cleararea As New Rectangle(1, 29, 126, 34)
    16. Dim _cleararea As New LinearGradientBrush(cleararea, Color.White, Color.White, LinearGradientMode.Horizontal)
    17. ' Ein "Schwarzes Rechteck" definieren
    18. Dim filled As New Rectangle(0, 28, 128, 36)
    19. Dim _filled As New LinearGradientBrush(filled, Color.Black, Color.Black, LinearGradientMode.Horizontal)
    20. ' Datum usw auslesen
    21. Dim Jahr As Integer = Date.Now.Year
    22. Dim _Monat As Integer = Date.Now.Month
    23. Dim _Tag As Integer = Date.Now.DayOfWeek
    24. ' Monats-Tabelle
    25. Dim Monat_Liste() As String = {"Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"}
    26. ' Tag-Tabelle
    27. 'Dim Tag_Liste() As String = {"Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag", "Sonntag", "NOP"}
    28. Dim Tag_Liste() As String = {"Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"}
    29. ' Tag in der Tabelle auslesen und in einer Variable abspeichern
    30. Dim Monat As String = Monat_Liste(_Monat - 1)
    31. Debug.Print((_Tag).ToString)
    32. Dim Tag As String = Tag_Liste(_Tag)
    33. ' Schwarzer Rand zeichnen
    34. g.FillRectangle(_filled, filled)
    35. g.FillRectangle(_cleararea, cleararea)
    36. 'Datum und Uhr zeichnen
    37. g.DrawString(Tag & ", den " & Date.Now.Day.ToString & ".", fnt, Brushes.Black, 1, 1)
    38. g.DrawString(Monat & " " & Jahr.ToString, fnt, Brushes.Black, 1, 12)
    39. g.DrawString(Date.Now.ToString("HH:mm:ss"), DIGIT, Brushes.Black, 1, 27)
    40. Debug.Print("1=D")
    41. ElseIf _NUM = 2 Then
    42. Debug.Print("2=(")
    43. '---Analoguhr
    44. 'Kreis zeichnen
    45. g.DrawEllipse(Pens.Black, 32, 0, 64, 64 - 1)
    46. ' radius herausfinden
    47. Dim radius As Single = (64 \ 2)
    48. ' Den Mittelpunkt des kreises herausfinden
    49. Dim origin As New PointF(128 \ 2, 64 \ 2)
    50. Dim i As Single = 0.0F
    51. While i <> 390.0F
    52. ' Ziffern Zeichnen
    53. g.DrawLine(Pens.Black, PointOnCircle(radius - 1, i, origin), PointOnCircle(radius - 3, i, origin))
    54. i += 30.0F
    55. End While
    56. 'Sekundenzeiger zeichnen
    57. g.DrawLine(Pens.Black, origin, PointOnCircle(radius, DateTime.Now.Second * 6.0F, origin))
    58. 'Minutenzeiger zeichnen
    59. g.DrawLine(Pens.Black, origin, PointOnCircle(radius * 0.75F, DateTime.Now.Minute * 6.0F, origin))
    60. 'Stundenzeiger zeichnen
    61. g.DrawLine(Pens.Black, origin, PointOnCircle(radius * 0.5F, DateTime.Now.Hour * 30.0F, origin))
    62. End If
    63. Return _bmp
    64. End Function

    Das ist die Funktion in dem Plugin womit ich die Uhr aufrufe. Wenn ich diese Funktion direkt im Hauptprogramm habe, funktioniert sie. Nur wenn sie in einem Plugin ist, wills einfach nicht mehr...

    Kennt ihr vielleicht einen Grund oder (noch besser) eine Lösung zu meinem Problem?

    PS: Alles Option Strict ON ;D

    mfg

    gfc
    Also mal als grundlegende Regel: Wenn du mit dem Fehler nichts anfangen kannst, was verleitet dich dann zu der Annahme, wir könnten die Fehlermeldung nicht trotzdem wissen wollen, wenn wir dir helfen sollen?

    Mal so ins blaue geschossen würde ich vermuten, der Fehler liegt gar nicht in deinen geposteten Code-Teilen, sondern eher in dem Teil (bzw. der Logik dahinter), in dem dein Array availablePlugins gefüllt wird.
    Weltherrschaft erlangen: 1%
    Ist dein Problem erledigt? -> Dann markiere das Thema bitte entsprechend.
    Waren Beiträge dieser Diskussion dabei hilfreich? -> Dann klick dort jeweils auf den Hilfreich-Button.
    Danke.
    In dieser Variable sind nur die Pfade der Plugins drin.

    VB.NET-Quellcode

    1. Private Function GetAvailablePlugins() As Integer
    2. ' Plugin-Pfad bestimmen
    3. Dim appDir As String = My.Application.Info.DirectoryPath & Path.DirectorySeparatorChar & "PLUGINS"
    4. ' Pfade aller Plugins lesen
    5. availablePlugins = Directory.GetFiles(appDir, "*LCD.DLL")
    6. If availablePlugins.Length = 0 Then
    7. Debug.Print("Keine Plugins gefunden")
    8. Return Nothing
    9. Else
    10. Debug.Print("Mögliche Plugins gefunden")
    11. End If
    12. Dim count As Integer = 0
    13. ' Jedes Plugin auf seiner gültigkeit überprüfen
    14. For Each possiblePlugin As String In availablePlugins
    15. Dim asm As Assembly = Assembly.LoadFrom(possiblePlugin)
    16. Dim myType As System.Type = asm.GetType(asm.GetName.Name + ".Plugin")
    17. Dim plugin As LPlugin = CType(Activator.CreateInstance(myType), LPlugin)
    18. NameList = NameList & plugin.Name & "|"
    19. Debug.Print(asm.GetName.Name + " ist ein gültiges Plugin!")
    20. Debug.Print(plugin.Name & vbCrLf & plugin.Version & vbCrLf & plugin.Creator & vbCrLf & plugin.Descripton)
    21. count = count + 1
    22. Next
    23. Return count
    24. End Function

    Vom Clock-Plugin bekomme ich den Namen und alle andere Infos...
    Finde es deshalb sehr verwirrend, das die Funktion nicht will...
    Lol, ich sehe den Fehler den ich gemacht habe. Es zeit deswegen nichts an, weil ich "PictureBox1.Image = bmp" vergessen hab ^^

    Mein Clock-Plugin läuft also schonmal ^^
    Nun bekomme ich beim SYSviewer-plugin (Diverse Systemauslastungen) einen Fehler. Ich verwende darin ein PerformanceCounter.
    Der Fehler ist:
    Eine Ausnahme (erste Chance) des Typs "System.NullReferenceException" ist in SYSMON_LCD.dll aufgetreten.
    System.NullReferenceException: Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt.
    bei SYSMON_LCD.Plugin.ShowLCD(Bitmap _bmp, Int32 _NUM)
    Spoiler anzeigen

    VB.NET-Quellcode

    1. Function ShowLCD(ByVal _bmp As System.Drawing.Bitmap, ByVal _NUM As Integer) As Bitmap Implements LCDAPI.LPlugin.ShowLCD
    2. ' Zeilen und weiteres Definieren
    3. Try
    4. Dim i As Integer
    5. Dim y As Integer
    6. Dim cdrive As System.IO.DriveInfo
    7. Dim zeile1 As Integer = 4
    8. Dim zeile2 As Integer = 16
    9. Dim zeile3 As Integer = 28
    10. Dim zeile4 As Integer = 40
    11. Dim fnt As Font = New Font("Courier New", 8)
    12. Dim pen As New System.Drawing.Pen(Color.Black, 1)
    13. Dim PC As PerformanceCounter
    14. Dim PCI As PerformanceCounterCategory
    15. ' Grafikbereich bereitstellen
    16. Dim g As System.Drawing.Graphics = Drawing.Graphics.FromImage(_bmp)
    17. 'Grafikfläche bereinigen
    18. Dim clearall As New Rectangle(0, 0, 128, 64)
    19. Dim clearallbrush As New LinearGradientBrush(clearall, Color.White, Color.White, LinearGradientMode.Horizontal)
    20. g.FillRectangle(clearallbrush, clearall)
    21. ' Textrenderer herunterschrauben (Keine Graustufen)
    22. g.TextRenderingHint = Drawing.Text.TextRenderingHint.SingleBitPerPixelGridFit
    23. ' Kategorieren und Leere Ladebalken zeichen
    24. g.DrawString("CPU", fnt, Brushes.Black, 0, zeile1 - 1)
    25. g.DrawRectangle(pen, 28, zeile1, 65, 10)
    26. g.DrawString("RAM", fnt, Brushes.Black, 0, zeile2 - 1)
    27. g.DrawRectangle(pen, 28, zeile2, 65, 10)
    28. g.DrawString("DSK", fnt, Brushes.Black, 0, zeile3 - 1)
    29. g.DrawRectangle(pen, 28, zeile3, 65, 10)
    30. g.DrawString("NET", fnt, Brushes.Black, 0, zeile4 - 1)
    31. ' -CPU-
    32. ' CPU-Infos auslesen
    33. PC.CategoryName = "Prozessor"
    34. PC.CounterName = "Prozessorzeit (%)"
    35. PC.InstanceName = "_Total"
    36. i = CInt(PC.NextValue)
    37. y = CInt((65 * i) / 100)
    38. If y = 0 Then y = 1
    39. Dim rect As New Rectangle(28, zeile1, y, 10)
    40. g.DrawString(i.ToString + "%", fnt, Brushes.Black, 95, zeile1 - 1)
    41. Dim gradientBrush As New LinearGradientBrush(rect, Color.Black, Color.Black, LinearGradientMode.Horizontal)
    42. g.FillRectangle(gradientBrush, rect)
    43. ' -RAM-
    44. ' RAM-Infos auslesen
    45. PC.CategoryName = "Arbeitsspeicher"
    46. PC.CounterName = "Zugesicherte verwendete Bytes (%)"
    47. PC.InstanceName = Nothing
    48. i = CInt(PC.NextValue)
    49. y = CInt((65 * i) / 100)
    50. If y = 0 Then y = 1
    51. rect = New Rectangle(28, zeile2, y, 10)
    52. g.DrawString(i.ToString + "%", fnt, Brushes.Black, 95, zeile2 - 1)
    53. gradientBrush = New LinearGradientBrush(rect, Color.Black, Color.Black, LinearGradientMode.Horizontal)
    54. g.FillRectangle(gradientBrush, rect)
    55. ' -DISK C:\-
    56. ' DSK-Infos auslesen
    57. cdrive = My.Computer.FileSystem.GetDriveInfo("C:\")
    58. i = CInt((100 * (cdrive.TotalSize - cdrive.AvailableFreeSpace) / cdrive.TotalSize))
    59. y = CInt((65 * i) / 100)
    60. If y = 0 Then y = 1
    61. rect = New Rectangle(28, zeile3, y, 10)
    62. g.DrawString(i.ToString + "%", fnt, Brushes.Black, 95, zeile3 - 1)
    63. gradientBrush = New LinearGradientBrush(rect, Color.Black, Color.Black, LinearGradientMode.Horizontal)
    64. g.FillRectangle(gradientBrush, rect)
    65. 'Netzwerk Up- & Download lesen
    66. PC.CategoryName = "Netzwerkschnittstelle"
    67. PC.CounterName = "Empfangene Bytes/s"
    68. PC.InstanceName = PCI.GetInstanceNames(CInt("{0}"))
    69. Dim up As Integer = CInt(Math.Round(PC.NextValue / 1024))
    70. PC.CounterName = "Empfangene Bytes/s"
    71. Dim dn As Integer = CInt(Math.Round(PC.NextValue / 1024))
    72. Dim speed As String = " kB/s"
    73. 'Überprüfung, ob die Variable "Zu gross" ist und entsprechend umrechnen...
    74. If up > 9999 Then
    75. up = CInt(Math.Round(up / 1024))
    76. speed = " MB/s"
    77. End If
    78. If dn > 9999 Then
    79. dn = CInt(Math.Round(dn / 1024))
    80. speed = " MB/s"
    81. End If
    82. g.DrawString("UP " + up.ToString + speed, fnt, Brushes.Black, 25, zeile4 - 1)
    83. g.DrawString("DN " + dn.ToString + speed, fnt, Brushes.Black, 25, zeile4 + 9)
    84. Catch ex As Exception
    85. Debug.Print(ex.ToString)
    86. End Try
    87. Return _bmp
    88. End Function

    Mit der Try-Catch konnte ich sehen, das es am PerformaneCounter liegen muss (Keine Daten gezeichnet...). Gibt es eine andere (vielleicht bessere) Lösung um diverse Systemauslastungen auszulesen? Mir ist es vorallem wichtig, das ich aus die Netzwerkauslastung auslesen kann, kenne jedoch nur die PerformanceCounter-Variante.

    @ErfinderDesRades
    Naja, da hast du zwar Recht. Aber wie würde Firefox aussehen man keine AddOns installieren könnte? ;D
    Und so lerne ich mal was neues =) (Und wie man mit OptionStrict programmiert ^^ )

    mfg

    gfc
    Danke, nun bekomme ich schonmal keinen Fehler mehr.

    Jedoch zeigt er mir nur die RAM und Disk-Auslastung an. CPU und Netzwerk (up/down) sind immer auf 0 ohne ein Fehler anzuzeigen.
    Ich habe mir kurz eine testapp gemacht und wenn ich es als Control im FormDesigner einfüge und konfiguriere, geht es. Jedoch so wie es in der Funktion ist, will es nicht Funkionieren :o

    Kann es sein, das der PerformanceCounter etwas "unstabil" ist? Habe in Google schon einige Post's gelesen wo dieser teikweise nicht funktioniert...
    Das Problem hat sich von selbst erledigt. Ich habe für die CPU und für die Netzwerkauslastung ausserhalb der Funktion den PerformanceCounter definiert und so klappt alles.

    Danke für eure Hilfe =)

    mfg

    gfc