装配已被篡改

时间:2014-05-27 12:32:28

标签: c# assemblies

我正在尝试将第三方库嵌入到我的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);

发生异常

1 个答案:

答案 0 :(得分:2)

假设这些陈述在哪里正确(请注意这些陈述由原始帖子张贴在问题下方的评论中):

  1. “..的类型初始值设定项引发异常。”在iConfServer.NET.iConfServerDotNet..ctor()“
  2. 调试时,程序集具有适当的信息
  3. 问题可能在于你调用构造函数的方式。我已经创建了一个简单的测试库来向您展示如何正确地执行此操作:

    首先,测试库:

    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);