我正在尝试将第三方库嵌入到我的DLL中。 DLL已被引用并设置为不复制本地以及添加到资源。然后我执行以下操作以在运行时加载DLL。
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
string resourceName = new AssemblyName(args.Name).Name + ".dll";
string resource = Array.Find(Assembly.GetExecutingAssembly().GetManifestResourceNames(), element => element.EndsWith(resourceName));
Assembly assembly;
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource))
{
Byte[] assemblyData = new Byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
assembly = Assembly.Load(assemblyData);
stream.Close();
}
return assembly;
};
返回程序集,我可以进一步进入代码,但是当从DLL的构造函数实例化一个新对象时,我收到一个TypeInitilizationException,内部消息说“程序集已被篡改”。
无论如何,或者我的加载DLL的方法是错误的吗?
修改
instance = new iConfServerDotNet();
也尝试了
System.Reflection.ConstructorInfo constructorInfo = typeof(iConfServerDotNet).GetConstructor(new Type[] { });
if (constructorInfo.DeclaringType.Name == "iConfServerDotNet")
{
object o = constructorInfo.Invoke(new Object[] { }) as UserControl;
}
编辑2
获取类类型的新代码...并将其命名为contstructor。这仍然会导致相同的异常。
AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
{
string resourceName = new AssemblyName(args.Name).Name + ".dll";
string resource = Array.Find(Assembly.GetExecutingAssembly().GetManifestResourceNames(), element => element.EndsWith(resourceName));
Assembly assembly;
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource))
{
Byte[] assemblyData = new Byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
assembly = Assembly.Load(assemblyData);
stream.Close();
}
Type type = assembly.GetModule(resourceName).GetType("iConfServer.NET.iConfServerDotNet");
//object instance = type.GetConstructors()[0].Invoke(null);
object instance = Activator.CreateInstance(type);
return assembly;
};
Activator.CreatInstance(type);
发生异常答案 0 :(得分:2)
假设这些陈述在哪里正确(请注意这些陈述由原始帖子张贴在问题下方的评论中):
问题可能在于你调用构造函数的方式。我已经创建了一个简单的测试库来向您展示如何正确地执行此操作:
首先,测试库:
namespace TestLibrary
{
public class Main
{
public string GetString()
{
return "Hey, I'm working well!";
}
}
}
我已将其编译为动态链接库(.DLL)并将其作为引用添加到控制台应用程序项目中(同样,仅用于测试)。
作为备注,我更改了资源的Build Action
属性(您可以通过右键单击Solution Explorer
中的资源并单击Properties
)来打开属性窗口Embedded Resource
。
这是您的代码(我刚刚更改了第一部分,因为我不需要它,可以随意更改它)将库加载到我们正在运行的应用程序中:
string resourceName = "TestLibrary.dll";
string resource = Array.Find(Assembly.GetExecutingAssembly().GetManifestResourceNames(), element => element.EndsWith(resourceName));
Assembly assembly;
using (var stream = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource))
{
Byte[] assemblyData = new Byte[stream.Length];
stream.Read(assemblyData, 0, assemblyData.Length);
assembly = Assembly.Load(assemblyData);
stream.Close();
}
现在,要创建类的新实例,我们首先需要找到类的类型:
Type _typeOfClass = assembly.GetModule("TestLibrary.dll").GetType("TestLibrary.Main");
_typeOfClass
现在将包含引导我们进入库中Main
类的类型。
接下来我们将创建一个新的类实例,我们将调用GetString
方法来查看它是否真的有效:
// Create an instance of the class invoking the (only) constructor.
object _instance = _typeOfClass.GetConstructors()[0].Invoke(null);
// Call the method on the instance we just instantiated
object result = _typeOfClass.GetMethod("GetString").Invoke(_instance, null);
Console.WriteLine(result);
控制台现在将显示:嘿,我工作正常!。
如果您有多个构造函数而您只想获取默认构造函数(无参数),那么您也可以使用object _instance = Activator.CreateInstance(_typeOfClass);
。