Explicit Linking of DLL's in VB.net

  • Thread starter Thread starter Noone
  • Start date Start date
N

Noone

Hello all,

Ok, I want to create a program that will load plugins (dll's) from a
plugin folder. I can create the forms and put them into a dll but I
cannot actually add them dynamically at run time. I have tried to use
the LoadLibrary and GetProc functions, which sort of worked. I got
the pointer to the function but I cannot actually RUN the function
like I can in C++. I have heard some things about Invoking(?) I
believe but I cannot find enough about it. Any comments or
suggestions would be EXTREMELY helpful.

Thanks,

Josh
 
Well i did this with an interface



here is my reallife code from a wotking project ( sorry comments are for my
co workers and they are Dutch )

'--------------------------------------------------------------------------------------

'---

'--- clsGetObjectFromFile

'---

'--- Purpose : start returns an initiated IiQueuObject

'---

'--- Made by : Michel Posseth [MCP]

'--- Date : 14-11-2006

'--- Revissions : 21-11-2006 : AssPath ingebouwd voor flexibiliteid

'---

'--------------------------------------------------------------------------------------

Option Strict On

Option Explicit On

Imports System.IO

Public Class clsGetObjectFromFile

''' <summary>

''' Laad een object by zijn assembly naam en class naam

''' het te laden object moet een IiQueuObject interface bezitten

''' </summary>

''' <param name="vstrAssemblyName">Name of the VSTR assembly.</param>

''' <param name="vstrClassName">Name of the VSTR class.</param>

''' <returns></returns>

Public Shared Function LoadMeByName(ByVal vstrAssemblyName As String, _

ByVal vstrClassName As String) As ista.IiQueuObject

'<21-11-2006 MP>

If vstrAssemblyName.StartsWith("[AssPath]") Then

Dim appath As String =
System.Reflection.Assembly.GetExecutingAssembly.Location

vstrAssemblyName = vstrAssemblyName.Replace("[AssPath]", "")

vstrAssemblyName = Path.Combine(appath, vstrAssemblyName)

End If

'</21-11-2006 MP>

Dim objAssembly As Reflection.Assembly

If Not My.Computer.FileSystem.FileExists(vstrAssemblyName) Then

ServMain.WriteLogentry("Assembly niet aanwezig : " & vstrAssemblyName,
EventLogEntryType.Error)

'de assembly is niet aanwezig op deze lokatie

Return Nothing

End If

objAssembly = Reflection.Assembly.LoadFrom(vstrAssemblyName)

'voer een cast uit naar ista.IiQueuObject interface

Try

LoadMeByName = DirectCast(objAssembly.CreateInstance(vstrClassName),
ista.IiQueuObject)

Catch ex As Exception

ServMain.WriteLogentry("Assembly bezit niet de juiste interface : " &
vstrAssemblyName, EventLogEntryType.Error)

Return Nothing

End Try

If LoadMeByName Is Nothing Then

Dim msg As String

msg = "Assembly : " & vstrAssemblyName & Environment.NewLine & _

"Type : " & vstrClassName & " is niet gestart om onduidelijke reden"

ServMain.WriteLogentry(msg, EventLogEntryType.Error)

'geen error gewoon niets terug geven

'wanneer we dus iets anders hebben als een Nothing pointer

'dan hebben we een geinitialiseerd object

Return Nothing

End If

End Function

End Class





here is my generic interface

'--------------------------------------------------------------------------------------

'---

'--- Purpose : Provide an generic interface for the Queu

'---

'--- Made by : Michel Posseth [MCP]

'--- Date : 20-11-2006

'--- Revissions :

'---

'--- Remarks : Do not break the interface signature !!

'--- you may extend but never remove property`s or methods

'---

'--------------------------------------------------------------------------------------

Option Strict On

Option Explicit On

Public Interface IiQueuObject

Sub StartProcessing()

Property Parameters() As String

Property ProcessId() As String

Event eFinished(ByVal ProcessId As String, ByVal msg As String)

Event eError(ByVal ProcessId As String, ByVal msg As String)

Event eProcessCancelled(ByVal ProcessId As String, ByVal msg As String)

Property CancellProcess() As Boolean

End Interface



now i can just use anny object like this

'het object welke we gaan starten

'OTask wordt gedefinieerd as ista.IiQueuObject

'we kunnen dus ieder mogelijk object opstarten indien het deze interface
heeft geimplementeerd

Dim oTask As ista.IiQueuObject =
clsGetObjectFromFile.LoadMeByName(Dr.Item("AssemblyNaam").ToString,
Dr.Item("AssemblyType").ToString)

If Not IsNothing(oTask) Then

otask.StartProcessing()

end if


HTH

Michel Posseth [MCP]
 
Thank you very much for the post but I have no idea what you are
doing. I have never worked with any of the "Reflection" classes. I
am a bit newer to VB.net so I think I am missing something. Can you
explain what is going on in more detail and less Dutch? hehe... : )

Thanks,

Josh

Well i did this with an interface



here is my reallife code from a wotking project ( sorry comments are for my
co workers and they are Dutch )

'--------------------------------------------------------------------------------------

'---

'--- clsGetObjectFromFile

'---

'--- Purpose : start returns an initiated IiQueuObject

'---

'--- Made by : Michel Posseth [MCP]

'--- Date : 14-11-2006

'--- Revissions : 21-11-2006 : AssPath ingebouwd voor flexibiliteid

'---

'--------------------------------------------------------------------------------------

Option Strict On

Option Explicit On

Imports System.IO

Public Class clsGetObjectFromFile

''' <summary>

''' Laad een object by zijn assembly naam en class naam

''' het te laden object moet een IiQueuObject interface bezitten

''' </summary>

''' <param name="vstrAssemblyName">Name of the VSTR assembly.</param>

''' <param name="vstrClassName">Name of the VSTR class.</param>

''' <returns></returns>

Public Shared Function LoadMeByName(ByVal vstrAssemblyName As String, _

ByVal vstrClassName As String) As ista.IiQueuObject

'<21-11-2006 MP>

If vstrAssemblyName.StartsWith("[AssPath]") Then

Dim appath As String =
System.Reflection.Assembly.GetExecutingAssembly.Location

vstrAssemblyName = vstrAssemblyName.Replace("[AssPath]", "")

vstrAssemblyName = Path.Combine(appath, vstrAssemblyName)

End If

'</21-11-2006 MP>

Dim objAssembly As Reflection.Assembly

If Not My.Computer.FileSystem.FileExists(vstrAssemblyName) Then

ServMain.WriteLogentry("Assembly niet aanwezig : " & vstrAssemblyName,
EventLogEntryType.Error)

'de assembly is niet aanwezig op deze lokatie

Return Nothing

End If

objAssembly = Reflection.Assembly.LoadFrom(vstrAssemblyName)

'voer een cast uit naar ista.IiQueuObject interface

Try

LoadMeByName = DirectCast(objAssembly.CreateInstance(vstrClassName),
ista.IiQueuObject)

Catch ex As Exception

ServMain.WriteLogentry("Assembly bezit niet de juiste interface : " &
vstrAssemblyName, EventLogEntryType.Error)

Return Nothing

End Try

If LoadMeByName Is Nothing Then

Dim msg As String

msg = "Assembly : " & vstrAssemblyName & Environment.NewLine & _

"Type : " & vstrClassName & " is niet gestart om onduidelijke reden"

ServMain.WriteLogentry(msg, EventLogEntryType.Error)

'geen error gewoon niets terug geven

'wanneer we dus iets anders hebben als een Nothing pointer

'dan hebben we een geinitialiseerd object

Return Nothing

End If

End Function

End Class





here is my generic interface

'--------------------------------------------------------------------------------------

'---

'--- Purpose : Provide an generic interface for the Queu

'---

'--- Made by : Michel Posseth [MCP]

'--- Date : 20-11-2006

'--- Revissions :

'---

'--- Remarks : Do not break the interface signature !!

'--- you may extend but never remove property`s or methods

'---

'--------------------------------------------------------------------------------------

Option Strict On

Option Explicit On

Public Interface IiQueuObject

Sub StartProcessing()

Property Parameters() As String

Property ProcessId() As String

Event eFinished(ByVal ProcessId As String, ByVal msg As String)

Event eError(ByVal ProcessId As String, ByVal msg As String)

Event eProcessCancelled(ByVal ProcessId As String, ByVal msg As String)

Property CancellProcess() As Boolean

End Interface



now i can just use anny object like this

'het object welke we gaan starten

'OTask wordt gedefinieerd as ista.IiQueuObject

'we kunnen dus ieder mogelijk object opstarten indien het deze interface
heeft geimplementeerd

Dim oTask As ista.IiQueuObject =
clsGetObjectFromFile.LoadMeByName(Dr.Item("AssemblyNaam").ToString,
Dr.Item("AssemblyType").ToString)

If Not IsNothing(oTask) Then

otask.StartProcessing()

end if


HTH

Michel Posseth [MCP]













Noone said:
Sorry, not invoke, I meant Interop. I think... Heeelp! : )
 
Hi Josh,

What kind of plugin dll you are trying to link, .Net assembly dll or pure
unmanaged code dll? If it is unmanaged code dll, then is the function you
want to call exported as function API through dll export table or the COM
dll?

If this is a .Net assembly dll, the recommended way of calling methods in
the dll is using .Net Reflection Michel pointed out. Reflection is a .Net
feature which allows us to dynamically load other .Net types and
dynamically call the members of the loaded types. Please refer to the
articles below for a start(although it is in language C#, the idea is the
same for all .Net languages):
"An Introduction to Reflection in C#"
http://www.codeguru.com/csharp/csharp/cs_misc/reflection/article.php/c4257__
1
"Reflection in .NET"
http://www.c-sharpcorner.com/UploadFile/harishankar2005/Reflectionin.NET1203
2005045926AM/Reflectionin.NET.aspx

Regarding unmanaged Win32 dll exported functions; you should use p/invoke
technology in .Net to get it done. Below article is a good start:
"Calling Win32 DLLs in C# with P/Invoke"
http://msdn.microsoft.com/msdnmag/issues/03/07/NET/

If your dll is a legacy COM dll, the solution is COM interop. COM interop
is a big topic, please refer to the article below:
"Introduction to COM Interop"
http://msdn.microsoft.com/msdnmag/issues/07/01/CLRInsideOut/default.aspx

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hello Noone

The concept is pretty simple

1. create a generic interface and compile this to a dll
2. create your plugin and implement the interface in the class you want to
start from the outside

3. create a application and set a reference to the interface dll

now you do

Dim objAssembly As Reflection.Assembly
objAssembly = Reflection.Assembly.LoadFrom(FullPathToAssemblyDllOrExe)

Dim YourObject as Yourinterface =
DirectCast(objAssembly.CreateInstance(Namespace.YourClassToInvoke),
Yourinterface)

Note :
Namespace.YourClassToInvoke ( namespace defaults to the assembly name but
can be set under project , properties , application , root namespace )

And that`s it !! :-)

YourObject is now initiated and can be controled from your code with the
interface that you provided

if You need anny more help feel free to ask ( i can create a small demo for
you and upload it to my server for you to download )


Regards

Michel Posseth





Noone said:
Thank you very much for the post but I have no idea what you are
doing. I have never worked with any of the "Reflection" classes. I
am a bit newer to VB.net so I think I am missing something. Can you
explain what is going on in more detail and less Dutch? hehe... : )

Thanks,

Josh

Well i did this with an interface



here is my reallife code from a wotking project ( sorry comments are for my
co workers and they are Dutch )

'--------------------------------------------------------------------------------------

'---

'--- clsGetObjectFromFile

'---

'--- Purpose : start returns an initiated IiQueuObject

'---

'--- Made by : Michel Posseth [MCP]

'--- Date : 14-11-2006

'--- Revissions : 21-11-2006 : AssPath ingebouwd voor flexibiliteid

'---

'--------------------------------------------------------------------------------------

Option Strict On

Option Explicit On

Imports System.IO

Public Class clsGetObjectFromFile

''' <summary>

''' Laad een object by zijn assembly naam en class naam

''' het te laden object moet een IiQueuObject interface bezitten

''' </summary>

''' <param name="vstrAssemblyName">Name of the VSTR assembly.</param>

''' <param name="vstrClassName">Name of the VSTR class.</param>

''' <returns></returns>

Public Shared Function LoadMeByName(ByVal vstrAssemblyName As String, _

ByVal vstrClassName As String) As ista.IiQueuObject

'<21-11-2006 MP>

If vstrAssemblyName.StartsWith("[AssPath]") Then

Dim appath As String =
System.Reflection.Assembly.GetExecutingAssembly.Location

vstrAssemblyName = vstrAssemblyName.Replace("[AssPath]", "")

vstrAssemblyName = Path.Combine(appath, vstrAssemblyName)

End If

'</21-11-2006 MP>

Dim objAssembly As Reflection.Assembly

If Not My.Computer.FileSystem.FileExists(vstrAssemblyName) Then

ServMain.WriteLogentry("Assembly niet aanwezig : " & vstrAssemblyName,
EventLogEntryType.Error)

'de assembly is niet aanwezig op deze lokatie

Return Nothing

End If

objAssembly = Reflection.Assembly.LoadFrom(vstrAssemblyName)

'voer een cast uit naar ista.IiQueuObject interface

Try

LoadMeByName = DirectCast(objAssembly.CreateInstance(vstrClassName),
ista.IiQueuObject)

Catch ex As Exception

ServMain.WriteLogentry("Assembly bezit niet de juiste interface : " &
vstrAssemblyName, EventLogEntryType.Error)

Return Nothing

End Try

If LoadMeByName Is Nothing Then

Dim msg As String

msg = "Assembly : " & vstrAssemblyName & Environment.NewLine & _

"Type : " & vstrClassName & " is niet gestart om onduidelijke reden"

ServMain.WriteLogentry(msg, EventLogEntryType.Error)

'geen error gewoon niets terug geven

'wanneer we dus iets anders hebben als een Nothing pointer

'dan hebben we een geinitialiseerd object

Return Nothing

End If

End Function

End Class





here is my generic interface

'--------------------------------------------------------------------------------------

'---

'--- Purpose : Provide an generic interface for the Queu

'---

'--- Made by : Michel Posseth [MCP]

'--- Date : 20-11-2006

'--- Revissions :

'---

'--- Remarks : Do not break the interface signature !!

'--- you may extend but never remove property`s or methods

'---

'--------------------------------------------------------------------------------------

Option Strict On

Option Explicit On

Public Interface IiQueuObject

Sub StartProcessing()

Property Parameters() As String

Property ProcessId() As String

Event eFinished(ByVal ProcessId As String, ByVal msg As String)

Event eError(ByVal ProcessId As String, ByVal msg As String)

Event eProcessCancelled(ByVal ProcessId As String, ByVal msg As String)

Property CancellProcess() As Boolean

End Interface



now i can just use anny object like this

'het object welke we gaan starten

'OTask wordt gedefinieerd as ista.IiQueuObject

'we kunnen dus ieder mogelijk object opstarten indien het deze interface
heeft geimplementeerd

Dim oTask As ista.IiQueuObject =
clsGetObjectFromFile.LoadMeByName(Dr.Item("AssemblyNaam").ToString,
Dr.Item("AssemblyType").ToString)

If Not IsNothing(oTask) Then

otask.StartProcessing()

end if


HTH

Michel Posseth [MCP]













Noone said:
Sorry, not invoke, I meant Interop. I think... Heeelp! : )


Hello all,

Ok, I want to create a program that will load plugins (dll's) from a
plugin folder. I can create the forms and put them into a dll but I
cannot actually add them dynamically at run time. I have tried to use
the LoadLibrary and GetProc functions, which sort of worked. I got
the pointer to the function but I cannot actually RUN the function
like I can in C++. I have heard some things about Invoking(?) I
believe but I cannot find enough about it. Any comments or
suggestions would be EXTREMELY helpful.

Thanks,

Josh
 
Hah... Luckily it is looking like I am doing something right. With
further research that is exactly the way I went. I found I could load
a form exactly how you did it. I do have one question though. The
"YourObject" is a form and is limited to the form methods. How can I
send information and and forth from the main program to the external
dll? Any ideas? Right now I am limited to form.show, form.height,
etc etc. Nothing that I create...

Thanks!

Btw, for the previous post, it is a vb.net dll. Aka mananged, I
believe....? (can you tell I am a bit new to this?)

Hello Noone

The concept is pretty simple

1. create a generic interface and compile this to a dll
2. create your plugin and implement the interface in the class you want to
start from the outside

3. create a application and set a reference to the interface dll

now you do

Dim objAssembly As Reflection.Assembly
objAssembly = Reflection.Assembly.LoadFrom(FullPathToAssemblyDllOrExe)

Dim YourObject as Yourinterface =
DirectCast(objAssembly.CreateInstance(Namespace.YourClassToInvoke),
Yourinterface)

Note :
Namespace.YourClassToInvoke ( namespace defaults to the assembly name but
can be set under project , properties , application , root namespace )

And that`s it !! :-)

YourObject is now initiated and can be controled from your code with the
interface that you provided

if You need anny more help feel free to ask ( i can create a small demo for
you and upload it to my server for you to download )


Regards

Michel Posseth





Noone said:
Thank you very much for the post but I have no idea what you are
doing. I have never worked with any of the "Reflection" classes. I
am a bit newer to VB.net so I think I am missing something. Can you
explain what is going on in more detail and less Dutch? hehe... : )

Thanks,

Josh

Well i did this with an interface



here is my reallife code from a wotking project ( sorry comments are for my
co workers and they are Dutch )

'--------------------------------------------------------------------------------------

'---

'--- clsGetObjectFromFile

'---

'--- Purpose : start returns an initiated IiQueuObject

'---

'--- Made by : Michel Posseth [MCP]

'--- Date : 14-11-2006

'--- Revissions : 21-11-2006 : AssPath ingebouwd voor flexibiliteid

'---

'--------------------------------------------------------------------------------------

Option Strict On

Option Explicit On

Imports System.IO

Public Class clsGetObjectFromFile

''' <summary>

''' Laad een object by zijn assembly naam en class naam

''' het te laden object moet een IiQueuObject interface bezitten

''' </summary>

''' <param name="vstrAssemblyName">Name of the VSTR assembly.</param>

''' <param name="vstrClassName">Name of the VSTR class.</param>

''' <returns></returns>

Public Shared Function LoadMeByName(ByVal vstrAssemblyName As String, _

ByVal vstrClassName As String) As ista.IiQueuObject

'<21-11-2006 MP>

If vstrAssemblyName.StartsWith("[AssPath]") Then

Dim appath As String =
System.Reflection.Assembly.GetExecutingAssembly.Location

vstrAssemblyName = vstrAssemblyName.Replace("[AssPath]", "")

vstrAssemblyName = Path.Combine(appath, vstrAssemblyName)

End If

'</21-11-2006 MP>

Dim objAssembly As Reflection.Assembly

If Not My.Computer.FileSystem.FileExists(vstrAssemblyName) Then

ServMain.WriteLogentry("Assembly niet aanwezig : " & vstrAssemblyName,
EventLogEntryType.Error)

'de assembly is niet aanwezig op deze lokatie

Return Nothing

End If

objAssembly = Reflection.Assembly.LoadFrom(vstrAssemblyName)

'voer een cast uit naar ista.IiQueuObject interface

Try

LoadMeByName = DirectCast(objAssembly.CreateInstance(vstrClassName),
ista.IiQueuObject)

Catch ex As Exception

ServMain.WriteLogentry("Assembly bezit niet de juiste interface : " &
vstrAssemblyName, EventLogEntryType.Error)

Return Nothing

End Try

If LoadMeByName Is Nothing Then

Dim msg As String

msg = "Assembly : " & vstrAssemblyName & Environment.NewLine & _

"Type : " & vstrClassName & " is niet gestart om onduidelijke reden"

ServMain.WriteLogentry(msg, EventLogEntryType.Error)

'geen error gewoon niets terug geven

'wanneer we dus iets anders hebben als een Nothing pointer

'dan hebben we een geinitialiseerd object

Return Nothing

End If

End Function

End Class





here is my generic interface

'--------------------------------------------------------------------------------------

'---

'--- Purpose : Provide an generic interface for the Queu

'---

'--- Made by : Michel Posseth [MCP]

'--- Date : 20-11-2006

'--- Revissions :

'---

'--- Remarks : Do not break the interface signature !!

'--- you may extend but never remove property`s or methods

'---

'--------------------------------------------------------------------------------------

Option Strict On

Option Explicit On

Public Interface IiQueuObject

Sub StartProcessing()

Property Parameters() As String

Property ProcessId() As String

Event eFinished(ByVal ProcessId As String, ByVal msg As String)

Event eError(ByVal ProcessId As String, ByVal msg As String)

Event eProcessCancelled(ByVal ProcessId As String, ByVal msg As String)

Property CancellProcess() As Boolean

End Interface



now i can just use anny object like this

'het object welke we gaan starten

'OTask wordt gedefinieerd as ista.IiQueuObject

'we kunnen dus ieder mogelijk object opstarten indien het deze interface
heeft geimplementeerd

Dim oTask As ista.IiQueuObject =
clsGetObjectFromFile.LoadMeByName(Dr.Item("AssemblyNaam").ToString,
Dr.Item("AssemblyType").ToString)

If Not IsNothing(oTask) Then

otask.StartProcessing()

end if


HTH

Michel Posseth [MCP]













"Noone" <[email protected]> schreef in bericht
Sorry, not invoke, I meant Interop. I think... Heeelp! : )


Hello all,

Ok, I want to create a program that will load plugins (dll's) from a
plugin folder. I can create the forms and put them into a dll but I
cannot actually add them dynamically at run time. I have tried to use
the LoadLibrary and GetProc functions, which sort of worked. I got
the pointer to the function but I cannot actually RUN the function
like I can in C++. I have heard some things about Invoking(?) I
believe but I cannot find enough about it. Any comments or
suggestions would be EXTREMELY helpful.

Thanks,

Josh
 
Btw, for the previous post, it is a vb.net dll. Aka mananged, I
believe....? (can you tell I am a bit new to this?)

yes this technique will only work on managed assemblys ( exe or dll )
I do have one question though. The
"YourObject" is a form and is limited to the form methods. How can I
send information and and forth from the main program to the external
dll?

Wel implement propertys , methods , events in your interface and start
comunicating :-)
i thought this is the easiest way , however it is possible to send
parameters to the constructor ( in the CreateInstance method )
however i didn`t bother as i comunicate through my interface with the object
( send parameters through properties, or methods , receive messages back
through events )

regards

Michel




Noone said:
Hah... Luckily it is looking like I am doing something right. With
further research that is exactly the way I went. I found I could load
a form exactly how you did it. I do have one question though. The
"YourObject" is a form and is limited to the form methods. How can I
send information and and forth from the main program to the external
dll? Any ideas? Right now I am limited to form.show, form.height,
etc etc. Nothing that I create...

Thanks!

Btw, for the previous post, it is a vb.net dll. Aka mananged, I
believe....? (can you tell I am a bit new to this?)

Hello Noone

The concept is pretty simple

1. create a generic interface and compile this to a dll
2. create your plugin and implement the interface in the class you want to
start from the outside

3. create a application and set a reference to the interface dll

now you do

Dim objAssembly As Reflection.Assembly
objAssembly = Reflection.Assembly.LoadFrom(FullPathToAssemblyDllOrExe)

Dim YourObject as Yourinterface =
DirectCast(objAssembly.CreateInstance(Namespace.YourClassToInvoke),
Yourinterface)

Note :
Namespace.YourClassToInvoke ( namespace defaults to the assembly name
but
can be set under project , properties , application , root namespace )

And that`s it !! :-)

YourObject is now initiated and can be controled from your code with the
interface that you provided

if You need anny more help feel free to ask ( i can create a small demo
for
you and upload it to my server for you to download )


Regards

Michel Posseth





Noone said:
Thank you very much for the post but I have no idea what you are
doing. I have never worked with any of the "Reflection" classes. I
am a bit newer to VB.net so I think I am missing something. Can you
explain what is going on in more detail and less Dutch? hehe... : )

Thanks,

Josh

On Wed, 31 Jan 2007 21:15:08 +0100, "Michel Posseth [MCP]"

Well i did this with an interface



here is my reallife code from a wotking project ( sorry comments are
for my
co workers and they are Dutch )

'--------------------------------------------------------------------------------------

'---

'--- clsGetObjectFromFile

'---

'--- Purpose : start returns an initiated IiQueuObject

'---

'--- Made by : Michel Posseth [MCP]

'--- Date : 14-11-2006

'--- Revissions : 21-11-2006 : AssPath ingebouwd voor flexibiliteid

'---

'--------------------------------------------------------------------------------------

Option Strict On

Option Explicit On

Imports System.IO

Public Class clsGetObjectFromFile

''' <summary>

''' Laad een object by zijn assembly naam en class naam

''' het te laden object moet een IiQueuObject interface bezitten

''' </summary>

''' <param name="vstrAssemblyName">Name of the VSTR assembly.</param>

''' <param name="vstrClassName">Name of the VSTR class.</param>

''' <returns></returns>

Public Shared Function LoadMeByName(ByVal vstrAssemblyName As String, _

ByVal vstrClassName As String) As ista.IiQueuObject

'<21-11-2006 MP>

If vstrAssemblyName.StartsWith("[AssPath]") Then

Dim appath As String =
System.Reflection.Assembly.GetExecutingAssembly.Location

vstrAssemblyName = vstrAssemblyName.Replace("[AssPath]", "")

vstrAssemblyName = Path.Combine(appath, vstrAssemblyName)

End If

'</21-11-2006 MP>

Dim objAssembly As Reflection.Assembly

If Not My.Computer.FileSystem.FileExists(vstrAssemblyName) Then

ServMain.WriteLogentry("Assembly niet aanwezig : " & vstrAssemblyName,
EventLogEntryType.Error)

'de assembly is niet aanwezig op deze lokatie

Return Nothing

End If

objAssembly = Reflection.Assembly.LoadFrom(vstrAssemblyName)

'voer een cast uit naar ista.IiQueuObject interface

Try

LoadMeByName = DirectCast(objAssembly.CreateInstance(vstrClassName),
ista.IiQueuObject)

Catch ex As Exception

ServMain.WriteLogentry("Assembly bezit niet de juiste interface : " &
vstrAssemblyName, EventLogEntryType.Error)

Return Nothing

End Try

If LoadMeByName Is Nothing Then

Dim msg As String

msg = "Assembly : " & vstrAssemblyName & Environment.NewLine & _

"Type : " & vstrClassName & " is niet gestart om onduidelijke reden"

ServMain.WriteLogentry(msg, EventLogEntryType.Error)

'geen error gewoon niets terug geven

'wanneer we dus iets anders hebben als een Nothing pointer

'dan hebben we een geinitialiseerd object

Return Nothing

End If

End Function

End Class





here is my generic interface

'--------------------------------------------------------------------------------------

'---

'--- Purpose : Provide an generic interface for the Queu

'---

'--- Made by : Michel Posseth [MCP]

'--- Date : 20-11-2006

'--- Revissions :

'---

'--- Remarks : Do not break the interface signature !!

'--- you may extend but never remove property`s or methods

'---

'--------------------------------------------------------------------------------------

Option Strict On

Option Explicit On

Public Interface IiQueuObject

Sub StartProcessing()

Property Parameters() As String

Property ProcessId() As String

Event eFinished(ByVal ProcessId As String, ByVal msg As String)

Event eError(ByVal ProcessId As String, ByVal msg As String)

Event eProcessCancelled(ByVal ProcessId As String, ByVal msg As String)

Property CancellProcess() As Boolean

End Interface



now i can just use anny object like this

'het object welke we gaan starten

'OTask wordt gedefinieerd as ista.IiQueuObject

'we kunnen dus ieder mogelijk object opstarten indien het deze
interface
heeft geimplementeerd

Dim oTask As ista.IiQueuObject =
clsGetObjectFromFile.LoadMeByName(Dr.Item("AssemblyNaam").ToString,
Dr.Item("AssemblyType").ToString)

If Not IsNothing(oTask) Then

otask.StartProcessing()

end if


HTH

Michel Posseth [MCP]













"Noone" <[email protected]> schreef in bericht
Sorry, not invoke, I meant Interop. I think... Heeelp! : )


Hello all,

Ok, I want to create a program that will load plugins (dll's) from a
plugin folder. I can create the forms and put them into a dll but I
cannot actually add them dynamically at run time. I have tried to
use
the LoadLibrary and GetProc functions, which sort of worked. I got
the pointer to the function but I cannot actually RUN the function
like I can in C++. I have heard some things about Invoking(?) I
believe but I cannot find enough about it. Any comments or
suggestions would be EXTREMELY helpful.

Thanks,

Josh
 
Hi Noone ,

Thanks for your feedback.

Yes, you may define several methods on this interface, which set
corresponding properties/methods. The below articles talks about this topic
to much deeper level:
"Using reflection to extend .NET programs"
http://www.codeproject.com/csharp/reflection.asp
"Dodge Common Performance Pitfalls to Craft Speedy Applications"
http://msdn.microsoft.com/msdnmag/issues/05/07/Reflection/default.aspx
"Let Users Add Functionality to Your .NET Applications with Macros and
Plug-Ins"
http://msdn.microsoft.com/msdnmag/issues/03/10/Plug-Ins/default.aspx

Hope this helps.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Absolutely amazing! Thank you so very much for all of your help.
Those links are exactly what I was looking for. It is amazing that
dotnet makes it so very easy to do run time binding so easy.

THANKS!!!
 
I really must be missing something. I have been looking through a lot
of the links provided in this post so I am starting to learn what I am
doing. However, I am still a bit confused..

Ok, I have a main program that loads dlls (which I got working). It
loads the dll and finds a form in the dll. I can even form1.show()
it. My question is, (and it may be quite... facinating... at 1 in the
morning) how can I get information to the main program using
properties from the dll when I don't know what the dll information
will hold?

Let me try again. I am not sure I am explaining myself correctly.

In the main application I have:

Dim extAssembly As System.Reflection.Assembly =
System.Reflection.Assembly.LoadFrom("c:\test.dll")
Dim extForm As Form = extAssembly.CreateInstance("test.entry",
True)
Me.AddOwnedForm(extForm)
extForm.Show()

Now how can I get information from the dll, as in it's name,
description, etc. when I can only use predefined functions like
Show(), etc? Basically how do I implement properties, methods, and
events that I can access from the main program?

See...? I am really missing something. And I know it is going to be
quite obvious too.... hehe.

Thanks for your help all!

-Josh

Btw, for the previous post, it is a vb.net dll. Aka mananged, I
believe....? (can you tell I am a bit new to this?)

yes this technique will only work on managed assemblys ( exe or dll )
I do have one question though. The
"YourObject" is a form and is limited to the form methods. How can I
send information and and forth from the main program to the external
dll?

Wel implement propertys , methods , events in your interface and start
comunicating :-)
i thought this is the easiest way , however it is possible to send
parameters to the constructor ( in the CreateInstance method )
however i didn`t bother as i comunicate through my interface with the object
( send parameters through properties, or methods , receive messages back
through events )

regards

Michel




Noone said:
Hah... Luckily it is looking like I am doing something right. With
further research that is exactly the way I went. I found I could load
a form exactly how you did it. I do have one question though. The
"YourObject" is a form and is limited to the form methods. How can I
send information and and forth from the main program to the external
dll? Any ideas? Right now I am limited to form.show, form.height,
etc etc. Nothing that I create...

Thanks!

Btw, for the previous post, it is a vb.net dll. Aka mananged, I
believe....? (can you tell I am a bit new to this?)

Hello Noone

The concept is pretty simple

1. create a generic interface and compile this to a dll
2. create your plugin and implement the interface in the class you want to
start from the outside

3. create a application and set a reference to the interface dll

now you do

Dim objAssembly As Reflection.Assembly
objAssembly = Reflection.Assembly.LoadFrom(FullPathToAssemblyDllOrExe)

Dim YourObject as Yourinterface =
DirectCast(objAssembly.CreateInstance(Namespace.YourClassToInvoke),
Yourinterface)

Note :
Namespace.YourClassToInvoke ( namespace defaults to the assembly name
but
can be set under project , properties , application , root namespace )

And that`s it !! :-)

YourObject is now initiated and can be controled from your code with the
interface that you provided

if You need anny more help feel free to ask ( i can create a small demo
for
you and upload it to my server for you to download )


Regards

Michel Posseth





:

Thank you very much for the post but I have no idea what you are
doing. I have never worked with any of the "Reflection" classes. I
am a bit newer to VB.net so I think I am missing something. Can you
explain what is going on in more detail and less Dutch? hehe... : )

Thanks,

Josh

On Wed, 31 Jan 2007 21:15:08 +0100, "Michel Posseth [MCP]"

Well i did this with an interface



here is my reallife code from a wotking project ( sorry comments are
for my
co workers and they are Dutch )

'--------------------------------------------------------------------------------------

'---

'--- clsGetObjectFromFile

'---

'--- Purpose : start returns an initiated IiQueuObject

'---

'--- Made by : Michel Posseth [MCP]

'--- Date : 14-11-2006

'--- Revissions : 21-11-2006 : AssPath ingebouwd voor flexibiliteid

'---

'--------------------------------------------------------------------------------------

Option Strict On

Option Explicit On

Imports System.IO

Public Class clsGetObjectFromFile

''' <summary>

''' Laad een object by zijn assembly naam en class naam

''' het te laden object moet een IiQueuObject interface bezitten

''' </summary>

''' <param name="vstrAssemblyName">Name of the VSTR assembly.</param>

''' <param name="vstrClassName">Name of the VSTR class.</param>

''' <returns></returns>

Public Shared Function LoadMeByName(ByVal vstrAssemblyName As String, _

ByVal vstrClassName As String) As ista.IiQueuObject

'<21-11-2006 MP>

If vstrAssemblyName.StartsWith("[AssPath]") Then

Dim appath As String =
System.Reflection.Assembly.GetExecutingAssembly.Location

vstrAssemblyName = vstrAssemblyName.Replace("[AssPath]", "")

vstrAssemblyName = Path.Combine(appath, vstrAssemblyName)

End If

'</21-11-2006 MP>

Dim objAssembly As Reflection.Assembly

If Not My.Computer.FileSystem.FileExists(vstrAssemblyName) Then

ServMain.WriteLogentry("Assembly niet aanwezig : " & vstrAssemblyName,
EventLogEntryType.Error)

'de assembly is niet aanwezig op deze lokatie

Return Nothing

End If

objAssembly = Reflection.Assembly.LoadFrom(vstrAssemblyName)

'voer een cast uit naar ista.IiQueuObject interface

Try

LoadMeByName = DirectCast(objAssembly.CreateInstance(vstrClassName),
ista.IiQueuObject)

Catch ex As Exception

ServMain.WriteLogentry("Assembly bezit niet de juiste interface : " &
vstrAssemblyName, EventLogEntryType.Error)

Return Nothing

End Try

If LoadMeByName Is Nothing Then

Dim msg As String

msg = "Assembly : " & vstrAssemblyName & Environment.NewLine & _

"Type : " & vstrClassName & " is niet gestart om onduidelijke reden"

ServMain.WriteLogentry(msg, EventLogEntryType.Error)

'geen error gewoon niets terug geven

'wanneer we dus iets anders hebben als een Nothing pointer

'dan hebben we een geinitialiseerd object

Return Nothing

End If

End Function

End Class





here is my generic interface

'--------------------------------------------------------------------------------------

'---

'--- Purpose : Provide an generic interface for the Queu

'---

'--- Made by : Michel Posseth [MCP]

'--- Date : 20-11-2006

'--- Revissions :

'---

'--- Remarks : Do not break the interface signature !!

'--- you may extend but never remove property`s or methods

'---

'--------------------------------------------------------------------------------------

Option Strict On

Option Explicit On

Public Interface IiQueuObject

Sub StartProcessing()

Property Parameters() As String

Property ProcessId() As String

Event eFinished(ByVal ProcessId As String, ByVal msg As String)

Event eError(ByVal ProcessId As String, ByVal msg As String)

Event eProcessCancelled(ByVal ProcessId As String, ByVal msg As String)

Property CancellProcess() As Boolean

End Interface



now i can just use anny object like this

'het object welke we gaan starten

'OTask wordt gedefinieerd as ista.IiQueuObject

'we kunnen dus ieder mogelijk object opstarten indien het deze
interface
heeft geimplementeerd

Dim oTask As ista.IiQueuObject =
clsGetObjectFromFile.LoadMeByName(Dr.Item("AssemblyNaam").ToString,
Dr.Item("AssemblyType").ToString)

If Not IsNothing(oTask) Then

otask.StartProcessing()

end if


HTH

Michel Posseth [MCP]













"Noone" <[email protected]> schreef in bericht
Sorry, not invoke, I meant Interop. I think... Heeelp! : )


Hello all,

Ok, I want to create a program that will load plugins (dll's) from a
plugin folder. I can create the forms and put them into a dll but I
cannot actually add them dynamically at run time. I have tried to
use
the LoadLibrary and GetProc functions, which sort of worked. I got
the pointer to the function but I cannot actually RUN the function
like I can in C++. I have heard some things about Invoking(?) I
believe but I cannot find enough about it. Any comments or
suggestions would be EXTREMELY helpful.

Thanks,

Josh
 
Breakthrough!!!

Ok, I am getting it. I can call the .InvokeMember function to call
external functions from the dll. That is what I was looking for.
PLEASE feel free to give me any comments or suggestions. Slight
breakthrough.... Need any advice you have. : )

Thanks,

Josh
 
Hi Josh,

Thanks for your feedback.

I am not sure I understand you completely. Do you mean Type.InvokeMember
method meet your need? However, how do you use Type.InvokeMember method to
call the external function(I assume external function means the methods
from the Exe modules) from the dll?

Based on my understanding, in the Exe main application, you may use
Assembly.Load/LoadFrom to obtain the assembly reference, then you got the
form reference through Assembly.CreateInstance. You may use
Assembly.GetType method to get the type reference of the "form" in the
assembly dll, and then use Type.InvokeMember() method to invoke any member
methods of the "form". Note, you should pass the original "form" object
reference as one parameter of Type.InvokeMember() method. Please search
"Type.InvokeMember" in MSDN. The MSDN for "Type.InvokeMember" contains some
sample code of using it. Also, the article below's "Dynamic Invocation with
Type.InvokeMember()" section may be informative to you:
http://www.codeproject.com/csharp/IntroReflection.asp

If you still have anything unclear or need any help, please feel free to
tell me, thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hello Josh,

Have you got any further progress on this? If you still have any questions,
please feel free to post here.

Sincerely,

Steven Cheng

Microsoft MSDN Online Support Lead


This posting is provided "AS IS" with no warranties, and confers no rights.
 
Hi Josh,

Have you reviewed my last reply to you? Does it make sense to you? If you
still need any help or have any concern, please feel free to tell me,
thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
Back
Top