martes, 19 de enero de 2010

Cargar un ensamblado DLL o Exe durante el tiempo de ejecucion

Bueno, pues ya tenia un poco descuidado mi blog, con el trabajo es dificil darse el espacio para continuar colocando entradas, pero tratare de ser mas constante, ok.

Y volviendo al tema, para empezar, la idea de esto comenzo con la inquietud de crear una aplicacion basada en plugins, que en el momento de su ejecucion verificara las Dlls existentes que contienen controles personalizados, y agregara dichos controles al formulario principal, esto me tomo un tiempo, ya que me involucre con situaciones de realizar llamadas a API, Hooks, e inclusive algunos manualillos que hay por ahi en la web que hablan de la inyeccion Dll, admito que estuve a punto de darme por vencido, pero como siempre, y despues de dormir un poco, ya mas despejado, y despues de leerme un curso sobre ensamblados y dominios de aplicacion, me sorprendio lo facil que es lograr esto, asi que aqui les va la solucion que encontre.

Resulta que mi aplicacion principal le coloque un control TabControl, para agrupar mis plugins (Mis dlls) en TabPages, asi que la intencion es crear un nuevo tabpage por cada Dll que este en el mismo directorio de mi aplicacion, y agregar el control que contiene.

Para esto haremos uso de la clase assembly que esta contenida en System.Reflection, esta clase nos permite instanciar un ensamblado el cual puede ser un Dll o un Exe, asi que aqui esta el metodo que cree explicado:


Public Sub AddAssembly(ByVal Path As String)

'Declaro mi objeto del tipo Assembly, y cargo el fichero
'El cual es el path donde se ubica mi dll
Dim MyAssembly As Assembly = Assembly.LoadFile(Path)

'Como el nombre de mi control, mi ensamblado y mi clase son iguales
'la referencia para un control instanciado de la clase MyControl seria
'MyControl.MyControl asi que aqui simplemente extraigo el nombre de mi
'archivo sin la extension, se vera algo rudimentario pero funciona :)
Dim sClase As String = MyAssembly.ManifestModule.Name.Split(CChar("."))(0)

'Aqui obtengo el tipo de dato que tengo en mi Dll
Dim MyExtType As Type = MyAssembly.GetType(sClase & "." & sClase)

'Entonces creo la instancia nueva de acuerdo al tipo de dato obtenido
'la almaceno en mi objeto tipo object
Dim MyExtObj As Object = Activator.CreateInstance(MyExtType)

'Creo mi tabPage
Dim NewTabPage As New TabPage

'Aqui convierto mi objeto a control, probablemente esto deberia ir en
'un try catch para obtener alguna exepcion, por ejemplo que la DLL no contenga
'controles
Dim MyControl As Control = CType(MyExtObj, Control)

'Agrego el nuevo control creado
NewTabPage.Controls.Add(MyControl)

'Agrego el nuevo TabPage a mi TabControl
form.TabControl1.TabPages.Add(NewTabPage)

End Sub



Asi solo mandamos a llamar a dicho metodo y como parametro utilizamos el path de la Dll, instancia el control y lo agrega a nuestro formulario principal.


Facil ¿no?, espero le ahorre un dolor de cabeza a alguien.

Probado en VS .Net 2008

No hay comentarios:

Publicar un comentario