Hallo Leute,
Ich probier zur Zeit mich mit dlls vertraut zu machen und probiere mit Hilfe von ihnen ein Pluginsystem zu entwickeln. Ich habe eine sehr gutes Tutorial von Fabian Stern gelesen, was mich schon sehr weit gebracht hat im Verständnis von dlls im Bezug auf Plugins.
Meine Frage wäre wie kann ich es schaffen, dass ich auf das Hauptprogramm aus den Funktionen des Plugins zugreifen kann, wie es auch die Funktionen des Hauptprogramms können.
Also umgefähr so:
myHost.Form1.Button2
myHost.testFunc("Test")
Hier mal das Beispiel aus dem Tutorial
Plugin:
PluginLoader
eigentliches Programm
Ich probier zur Zeit mich mit dlls vertraut zu machen und probiere mit Hilfe von ihnen ein Pluginsystem zu entwickeln. Ich habe eine sehr gutes Tutorial von Fabian Stern gelesen, was mich schon sehr weit gebracht hat im Verständnis von dlls im Bezug auf Plugins.
Meine Frage wäre wie kann ich es schaffen, dass ich auf das Hauptprogramm aus den Funktionen des Plugins zugreifen kann, wie es auch die Funktionen des Hauptprogramms können.
Also umgefähr so:
myHost.Form1.Button2
myHost.testFunc("Test")
Hier mal das Beispiel aus dem Tutorial
Plugin:
Code:
<Serializable()> Public Class clsPlugin 'Make it creatable on Runtime Inherits MarshalByRefObject 'AppDomain Compatibility Implements clsPluginLoader.IPlugin 'Link this class to the plugin interface IPlugin Dim myHost As clsPluginLoader.IHost Public Overrides Function InitializeLifeTimeService() As Object 'Make the plugin-lifetime unlimited (otherwise it will expire) Return Nothing End Function Public Sub SetHost(ByVal mHost As clsPluginLoader.IHost) Implements clsPluginLoader.IPlugin.SetHost myHost = mHost 'Set a link to objects of the main-application End Sub Public Function GetName() As String Implements clsPluginLoader.IPlugin.GetName 'Get the plugin name Return "MyPlugin by Timo Wiegel2" End Function Public Sub Load() Implements clsPluginLoader.IPlugin.Load 'When the plugin is loaded System.Windows.Forms.MessageBox.Show("Plugin is loaded 4Plugin") End Sub Public Sub Unload() Implements clsPluginLoader.IPlugin.Unload 'When the plugin is unloaded System.Windows.Forms.MessageBox.Show("Plugin is unloaded 4Plugin") End Sub Public Sub Run() Implements clsPluginLoader.IPlugin.Run myHost.myLabel.Text = "Plugin2" End Sub End Class
Code:
Public Interface IPlugin Function GetName() As String Sub Load() Sub Unload() Sub Run() Sub SetHost(ByVal mHost As IHost) End Interface Public Interface IHost Function myLabel() As System.Windows.Forms.Label Function myForm() As System.Windows.Forms.Form End Interface
eigentliches Programm
Code:
Public Class Form1 Inherits System.Windows.Forms.Form Implements clsPluginLoader.IHost #Region " Vom Windows Form Designer generierter Code " Public Sub New() MyBase.New() ' Dieser Aufruf ist für den Windows Form-Designer erforderlich. InitializeComponent() ' Initialisierungen nach dem Aufruf InitializeComponent() hinzufügen End Sub ' Die Form überschreibt den Löschvorgang der Basisklasse, um Komponenten zu bereinigen. Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean) If disposing Then If Not (components Is Nothing) Then components.Dispose() End If End If MyBase.Dispose(disposing) End Sub ' Für Windows Form-Designer erforderlich Private components As System.ComponentModel.IContainer 'HINWEIS: Die folgende Prozedur ist für den Windows Form-Designer erforderlich 'Sie kann mit dem Windows Form-Designer modifiziert werden. 'Verwenden Sie nicht den Code-Editor zur Bearbeitung. Friend WithEvents Label1 As System.Windows.Forms.Label Friend WithEvents lst As System.Windows.Forms.ListBox Friend WithEvents Label2 As System.Windows.Forms.Label Friend WithEvents Button1 As System.Windows.Forms.Button Friend WithEvents Button2 As System.Windows.Forms.Button Friend WithEvents lblAccess As System.Windows.Forms.Label <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent() Me.Label1 = New System.Windows.Forms.Label Me.lst = New System.Windows.Forms.ListBox Me.Label2 = New System.Windows.Forms.Label Me.Button1 = New System.Windows.Forms.Button Me.Button2 = New System.Windows.Forms.Button Me.lblAccess = New System.Windows.Forms.Label Me.SuspendLayout() ' 'Label1 ' Me.Label1.Location = New System.Drawing.Point(8, 8) Me.Label1.Name = "Label1" Me.Label1.Size = New System.Drawing.Size(56, 16) Me.Label1.TabIndex = 0 Me.Label1.Text = "Functions:" ' 'lst ' Me.lst.Location = New System.Drawing.Point(16, 32) Me.lst.Name = "lst" Me.lst.Size = New System.Drawing.Size(184, 108) Me.lst.TabIndex = 1 ' 'Label2 ' Me.Label2.Location = New System.Drawing.Point(72, 8) Me.Label2.Name = "Label2" Me.Label2.Size = New System.Drawing.Size(128, 16) Me.Label2.TabIndex = 2 Me.Label2.Text = "(from plugins/ directory)" ' 'Button1 ' Me.Button1.Location = New System.Drawing.Point(16, 144) Me.Button1.Name = "Button1" Me.Button1.Size = New System.Drawing.Size(104, 24) Me.Button1.TabIndex = 3 Me.Button1.Text = "Unload All Plugins" ' 'Button2 ' Me.Button2.Location = New System.Drawing.Point(128, 144) Me.Button2.Name = "Button2" Me.Button2.Size = New System.Drawing.Size(72, 24) Me.Button2.TabIndex = 4 Me.Button2.Text = "Reload" ' 'lblAccess ' Me.lblAccess.Location = New System.Drawing.Point(216, 8) Me.lblAccess.Name = "lblAccess" Me.lblAccess.Size = New System.Drawing.Size(344, 160) Me.lblAccess.TabIndex = 5 ' 'Form1 ' Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) Me.ClientSize = New System.Drawing.Size(568, 171) Me.Controls.Add(Me.lblAccess) Me.Controls.Add(Me.Button2) Me.Controls.Add(Me.Button1) Me.Controls.Add(Me.Label2) Me.Controls.Add(Me.lst) Me.Controls.Add(Me.Label1) Me.Name = "Form1" Me.Text = "Main Plugin Form" Me.ResumeLayout(False) End Sub #End Region Dim mySetup As New AppDomainSetup Dim myAppDomain As AppDomain Dim myEvidence As System.Security.Policy.Evidence = AppDomain.CurrentDomain.Evidence Dim myPlugin() As clsPluginLoader.IPlugin Dim bLoaded As Boolean = False #Region "Free Available Host-Objects" Function myLabel() As Label Implements clsPluginLoader.IHost.myLabel Return lblAccess End Function #End Region Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Init_Plugins() End Sub Sub Init_Plugins() mySetup.ApplicationBase = System.Environment.CurrentDirectory myAppDomain = AppDomain.CreateDomain("AppBase", myEvidence, mySetup) ReDim myPlugin(0) 'Create Plugin Space If IO.Directory.Exists(Application.StartupPath & "\plugins") Then For Each myFile As String In IO.Directory.GetFiles(Application.StartupPath & "\plugins\") Dim myPI As Int32 = GetFreePlugin() Try myPlugin(myPI) = myAppDomain.CreateInstanceFromAndUnwrap(myFile, "clsPluginSample.clsPlugin") 'Add Plugin to myPlugin variable myPlugin(myPI).SetHost(Me) lst.Items.Add(myPlugin(myPI).GetName) 'Add Plugin Name myPlugin(myPI).Load() 'Execute the Load Sub INSIDE THE PLUGIN Catch ex As Exception Try 'On error delete the errorneous plugin myPlugin(myPI) = Nothing Catch End Try MessageBox.Show("Invalid module ignored: " & myFile & " [" & ex.Message & "]") End Try Next End If bLoaded = True 'All plugins loaded successfully End Sub Function GetFreePlugin() As Int32 For I As Int32 = 0 To myPlugin.GetUpperBound(0) If myPlugin(I) Is Nothing Then Return I Next Dim myUB As Int32 = myPlugin.GetUpperBound(0) + 1 ReDim Preserve myPlugin(myUB) Return myUB End Function Function GetPlugin(ByVal mName As String) As Int32 For I As Int32 = 0 To myPlugin.GetUpperBound(0) If Not myPlugin(I) Is Nothing Then If myPlugin(I).GetName = mName Then Return I End If Next Return -1 End Function Private Sub lst_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lst.SelectedIndexChanged Dim myI As Int32 = GetPlugin(CType(lst.SelectedItem, String)) If myI > -1 Then myPlugin(myI).Run() End Sub Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click For I As Int32 = 0 To myPlugin.GetUpperBound(0) If Not myPlugin(I) Is Nothing Then myPlugin(I).Unload() myPlugin(I) = Nothing End If Next If bLoaded Then AppDomain.Unload(myAppDomain) : bLoaded = False lst.Items.Clear() End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click If Not bLoaded Then Init_Plugins() : bLoaded = True End Sub End Class