[Solucionado] Cargar DLL a memoria

Iniciado por seba123neo, 15 Septiembre 2010, 02:58 AM

0 Miembros y 1 Visitante están viendo este tema.

seba123neo

te parece mal si te pido que subas el proyecto con el codigo ?
La característica extraordinaria de las leyes de la física es que se aplican en todos lados, sea que tú elijas o no creer en ellas. Lo bueno de las ciencias es que siempre tienen la verdad, quieras creerla o no.

Neil deGrasse Tyson

[D4N93R]

Lo subo mañana temprano en este mismo post, voy de salida. !

seba123neo

LISTOOOOOOOOOO  ;D ;D ;D , (paresco uno que recien empieza a programar y le sale el primer hola mundo jaja)

de tanto ver ejemplos comenze a ver como funciona realmente, puede que antes no lo tenia claro.

el error que estaba cometiendo es hacerlo en un formulario, o sea en el Load o el constructor del form, se ve que ahi no anda, porque el diseñador de windows forms lo carga antes de que yo haga la carga del assembly.

lo puse en un modulo con un Sub Main y funciona perfecto.

aclaro para el que no sabe que el evento AssemblyResolve se ejecuta cuando el programa no encuentra una dependencia, entonces ahi dentro del evento le podemos decir de donde sacar el assembly, si se lo pasamos mal obviamente se produce una excepción y se termina el programa.

como vos decias hay que usar el args.Name que devuelve la info del assembly que esta referenciado y no lo encuentra, este retorna el nombre de la libreria, la version, la cultura y el keytoken, algo asi:

Código (vbnet) [Seleccionar]
System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

entonces el codigo final queda asi:

Código (vbnet) [Seleccionar]
Imports System.IO
Imports System.Reflection

Module Module1
    Sub Main()
        AddHandler AppDomain.CurrentDomain.AssemblyResolve, AddressOf CargarLibreriaMemoria

        Application.EnableVisualStyles()
        Application.Run(Form1)
    End Sub

    Private Function CargarLibreriaMemoria(ByVal sender As Object, ByVal args As ResolveEventArgs) As Assembly

        Dim vNombre As String = args.Name.Substring(0, args.Name.IndexOf(","))

        Dim vStream As Stream = Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("WindowsApplication1." & vNombre & ".dll")
        Dim vBuffer As Byte() = New Byte(vStream.Length - 1) {}

        vStream.Read(vBuffer, 0, vBuffer.Length)

        Dim vLibreria As Assembly = Assembly.Load(vBuffer)

        Return vLibreria
    End Function
End Module


con eso lo que hago es solo sacar el nombre del ensamblado que esta antes de la primer coma, o sea:

System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

y listo con eso funciona...

obviamente debemos reemplazar WindowsApplication1 por el nombre de nuestro programa, yo lo puse asi fijo para ponerlo nomas, se puede averiguar desde codigo tambien.

si alguno quiere ver los nombres de los ensamblados que usa el programa lo puede ver asi:

Código (vbnet) [Seleccionar]
        For Each asm As Assembly In AppDomain.CurrentDomain.GetAssemblies()
            Dim name As String = asm.FullName.Substring(0, asm.FullName.IndexOf(","))
        Next


gracias por tu tiempo [D4N93R] , decime tu nombre porque no me gusta llamar por nick  ;D

saludos.
La característica extraordinaria de las leyes de la física es que se aplican en todos lados, sea que tú elijas o no creer en ellas. Lo bueno de las ciencias es que siempre tienen la verdad, quieras creerla o no.

Neil deGrasse Tyson

[D4N93R]

Que bueno que resolviste!, justo iba  subirte el proyecto.

El problema era que estabas haciendo el AssemblyResolve en la clase del form? AAAAAAAAAAA, my bad! yo lo hacía en la clase Program, entonces claro, fallala referencia antes de que pudieses subcribirte al evento  :xD

Pero bueno, mucho mejor que lo hayas resuelto solo, así se aprende mucho más, el framework todo es así, muy poderoso pero hay que entenderlo bien.

Un tip: puedes usar GetManifestResourceNames() en la clase assembly para obtener todos los recursos dentro del assembly, sea mediante Assembly.GetExecutingAssembly() o por cualquier carga (Load) de assemblies.

Un saludo.

PD: Juan.  ;D