2012-09-07 15 views
8

Estoy intentando cargar un ensamblado en tiempo de ejecución, y no estoy seguro de por qué no puedo crear una instancia de un tipo en el ensamblado utilizando la estática Activator.CreateInstance(). Funciona con Assembly.CreateInstance().Cargando ensamblajes en tiempo de ejecución y creando instancias usando Activator.CreateInstance()

string assemblyFilename = "MyAssembly.dll"; 
string assemblyName = "MyAssembly"; 
string typeName = "MyAssembly.MyType"; 

FileInfo fileInfo = new FileInfo(assemblyFilename); 

Esto funciona:

var assembly = Assembly.LoadFrom(assemblyFilename); 
Form form = (Form)assembly.CreateInstance(typeName); 

Pero esto no funciona:

Assembly.LoadFrom(assemblyFilename); 
Form form = (Form)Activator.CreateInstance(assemblyName, typeName).Unwrap(); 

FileNotFoundException arrojado:

No se pudo cargar el archivo o ensamblado 'MyAssembly' o uno de su dependencia ies. El sistema no puede encontrar el archivo especificado.

EDIT:

En ambos casos, después de la llamada Assembly.LoadFrom(), puedo ver que mi montaje se ha cargado cuando me miro en AppDomain.CurrentDomain.GetAssemblies().

+1

La segunda versión debe especificar un nombre de conjunto completo, no solo el nombre para mostrar, y usa Assembly.Load() debajo del capó. No es lo mismo que LoadFrom(). Solucionar problemas con fuslogvw.exe –

+0

Como en "MyAssembly, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = 5dc3e20777fed081"? Obtengo el mismo error – davenewza

+0

Incluso he copiado FullName directamente desde "MyAssembly" en GetAssemblies() y todavía no funciona. ¡Muy confundido! – davenewza

Respuesta

2

Usted tiene que cargar primero el conjunto en su dominio de aplicación actual:

AppDomain.CurrentDomain.Load(File.ReadAllBytes(assemblyFileName)); 

EDIT: ¿Funciona?

Form form = (Form)Activator.CreateInstance(Type.GetType(typeName)) 
+0

me sale el mismo problema. Si miro en 'AppDomain.CurrentDomain.GetAssemblies()' después de 'Assembly.LoadFrom()' entonces puedo ver que mi ensamblado se ha cargado en ambos casos. – davenewza

+1

@davenewza Revisa mi edición para ver si eso funciona –

+0

No es así. Obtengo "El valor no puede ser nulo" en 'Type.GetType()'. – davenewza

3

Puede ajustar su archivo con su ruta

var path = Assembly.GetAssembly(MyType.GetType()).Location; 
var thisAssembly= Assembly.LoadFrom(path); 

var TypeName = ""; 
Type type = thisAssembly.GetType(TypeName); 
object instance = Activator.CreateInstance(type); 
+0

Necesito usar Activator.CreateInstance() porque no siempre tendré disponible una instancia del ensamblado. – davenewza

+1

@davenewza he agregado el código para publicar –

1

Intenté editar la respuesta original pero no recibí respuesta del autor. Así que por si acaso alguien necesita esto, aquí está el código que trabajó para mí

System.Reflection.Assembly assembly = AppDomain.CurrentDomain.Load(File.ReadAllBytes("DLL_PATH")); 
Form form = (Form)assembly.CreateInstance("FullNameSpace.ClassName"); 
0

Una variación de la respuesta de un Khudairy aquí para permitir que pasa en los parámetros de entrada para acceder a un constructor específico, además de esta variación de su respuesta resuelta un problema que he tenido y, literalmente, he buscado por varias semanas tratando de resolverlo (muchas felicitaciones para él por compartir la respuesta).

Mi problema era que quería cargar un .NET 3.5 dll en una nueva aplicación que era .NET 4.6, pero los viejos dll's usaban controles de terceros que parecían usar la política de CAS. Obtendría un error de los controles de terceros diciendo que necesitaba entregar app.config; si lo hiciera, podría cargar y ejecutar los archivos correctamente si estuvieran en mi computadora local, pero si traté de cargarlos desde una unidad de red, que tengo que hacer, luego recibí un error de FileIOPermission.

tratado de ejecutar combinaciones de NetFx40_LegacySecurityPolicy con loadFromRemoteSources y useLegacyV2RuntimeActivationPolicy, e intentaron varios métodos diferentes, tales como Activator.CreateInstance(), que por lo general funciona para mí, intentaron crear una caja de arena (aunque no sé si lo hice correctamente), pero nada funcionaría, excepto por debajo. Tenga en cuenta que mis controles de usuario también se basaban en una clase base. Había ejecutado algunos comandos de símbolo del sistema de CAS antes de otorgar acceso a la unidad de red, y mi aplicación debería ejecutarse con plena confianza. A pesar de todo, no parecía ninguno de los métodos que había probado, aparte de que este ha funcionado hasta ahora para mí.

El código del arreglo:

object dllUserControl = null; 
System.Reflection.Assembly assembly = AppDomain.CurrentDomain.Load(File.ReadAllBytes("DLL_PATH")); 
dllUserControl = assembly.CreateInstance("FullNameSpace.ClassName",true,BindingFlags.Default,null,constructorParams[],null,null); 

... desde el cual podía convertir el objeto más adelante según sea necesario (a mi clase base) para poner en marcha más adelante en su propio Formulario/ventana.

Cuestiones relacionadas