精华内容
下载资源
问答
  • 程序集
    千次阅读
    2017-12-03 11:36:42

    C#程序集的定义



    程序集是包含一个或多个类型定义文件和资源文件的集合。它允许我们分离可重用类型的逻辑表示和物理表示。


    程序集是一个可重用、可实施版本策略和安全策略的单元。它允许我们将类型和资源划分到不同的文件中,这样程序集的使用者便可以决定将哪些文件打包在一起部署。一旦CLR加载了程序集中包含清单的那个文件,它就可以确定程序集的其它文件中哪些包含了程序正在引用的类型和资源。任何程序集的使用者仅需要知道包含清单的文件名称。文件的划分对使用都是透明的,并且可以在将来改变,同时又不会破坏现有的应用程序的行为。


    程序集的特性:


    1、程序集定义了可重用的类型。


    2、程序集标识有一个版本号。


    3、程序集可以包含与之相关的安全信息。


    二、多文件集:


    使用多文件集的三个原因:


    1、可以将类型分别实现在不同的文件中,从而允许文件在互联网环境中进行增量下载。


    2、可以按需要向程序集中添加资源或数据文件。(数据文件可以是任何格式:文本文件、excel电子表格、word表格、或者任何我们喜欢的格式)。


    3、可以使我们创建的程序集包含一些用不同编程语言实现的类型。


    三、程序链接器:


    程序链接器:Assembly Linker即AL.exe


    1、使用前提:


    如果我们要创建的程序集包含来自不同的编译器生成的模块,而使用的编译器又不支持类似于C#中/addmodule那样的命令行开关,或者生成模块时还不知道程序集的打包需求,这时程序集链接器就显示非常有用。


    四、程序集的分类:


    共享程序集:


    程序集可以是共享的,也可以是私有的。私有程序集位于应用程序所在的目录下,或其子目录下中。使用私有程序集是,不 需要考虑与其他类的命名冲突或版本冲突问题。在构建过程中引用的程序集会复制到应用程序的目录下。私有程序集是构建程序集的一般方式,特别是应用程序和组件在同一个公司中建立时,就更是如此。


    共享程序集:


    在使用共享程序集时,必须遵循一些规则。程序集必须是惟一的,因此,必须有一个惟一的名称(称为强名)。该名称的一部分是一个强制的版本号。当组件由另一个开发商构建,而不是应用程序的开发商构建时,以及一个大应用程序分布在几个小项目中时,常常需要使用共享程序集。
    ========

    C#中的程序集和反射介绍


    这篇文章主要介绍了C#中的程序集和反射介绍,程序集包含资源文件,类型元数据、IL代码,每个程序集都有自己的名称、版本等信息,反射就是动态获取程序集中的元数据的功能,需要的朋友可以参考下
    ..什么是程序集?


    1.程序集(assembly)是一个及一个以上托管模块,以及一些资源文件的逻辑组合。
    2.程序集是组件复用,以及实施安全策略和版本策略的最小单位。
    3.程序集是包含一个或者多个类型定义文件和资源文件的集合。在程序集包含的所有文件中,有一个文件用于保存清单。(清单是元数据部分中一组数据表的集合,其中包含了程序集中一部分文件的名称,描述了程序集的版本,语言文化,发布者,共有导出类型,以及组成该程序集的所有文件)。
    4、在编译应用程序中,所创建的CIL代码存储在一个程序集中,程序集包括可执行的应用程序文件(.exe扩展名文件)和其他应用程序使用的库(.dll扩展名文件)。


    作为一个单元进行版本控制和部署的一个或多个文件的集合。程序集是.NETFramework 应用程序的主要构造块。所有托管类型和资源都包含在某个程序集内,并被标记为只能在该程序集的内部访问,或者被标记为可以从其他程序集中的代码访问。程序集在安全方面也起着重要作用。代码访问安全系统使用程序集信息来确定为程序集中的代码授予的权限集。


    程序集是.NET Framework编程的基本组成部分。(此上是在百度百科的定义)
    简单的说,net中的dll和exe文件都是程序集


    程序集包含资源文件,类型元数据(描述在代码中定义的每一类型和成员,二进制形式)、IL代码(这些都被装在exe或dll中),每个程序集都有自己的名称、版本等信息。这些信息可以通过AssemblyInfo.cs文件来自己定义。




    复制代码 代码如下:
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Runtime.InteropServices;


    // 有关程序集的常规信息通过以下
    // 特性集控制。更改这些特性值可修改
    // 与程序集关联的信息。
    [assembly: AssemblyTitle("AssemblyDemo")]
    [assembly: AssemblyDescription("")]
    [assembly: AssemblyConfiguration("")]
    [assembly: AssemblyCompany("")]
    [assembly: AssemblyProduct("AssemblyDemo")]
    [assembly: AssemblyCopyright("Copyright ©  2013")]
    [assembly: AssemblyTrademark("")]
    [assembly: AssemblyCulture("")]


    // 将 ComVisible 设置为 false 使此程序集中的类型
    // 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
    // 则将该类型上的 ComVisible 特性设置为 true。
    [assembly: ComVisible(false)]


    // 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
    [assembly: Guid("e7da9959-0c97-444c-aa40-6d9bbf728068")]


    // 程序集的版本信息由下面四个值组成:
    //
    //      主版本
    //      次版本 
    //      内部版本号
    //      修订号
    //
    // 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
    // 方法是按如下所示使用“*”:
    // [assembly: AssemblyVersion("1.0.*")]
    [assembly: AssemblyVersion("1.0.0.0")]
    [assembly: AssemblyFileVersion("1.0.0.0")]


    AssemblyInfo.cs



    使用程序集的优点:


    程序只需要应用必要的程序集,减少了编码量(例如log4net.dll),程序的尺寸 。
    可以在程序集中封装一些代码,提供必要的接口,供引用该程序集的项目使用。   

    反射


    提到程序集,就不得不说反射。反射就是动态获取程序集中的元数据(提供程序集的类型信息)的功能。也就是动态获取程序集中的元数据来操作类型的。比如咱们使用的vs中的智能提示,就是通过反射获取类的方法、属性的。


    Type类是实现反射的一个很重要的类,通过它我们可以获取类中的所有信息包括方法、属性等。可以动态调用类的属性机及方法。


    Type是对类的描述。


    一个简单的例子新建一个类库MyAssembly添加Person类,生成:



    复制代码 代码如下:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
     
    namespace MyAssembly
    {
        public class Person
        {
            private string name;
     
            public string Name
            {
                get { return name; }
                set { name = value; }
            }
            private int age;
     
            public int Age
            {
                get { return age; }
                set { age = value; }
            }
            private string gender;
     
            public string Gender
            {
                get { return gender; }
                set { gender = value; }
            }
            public Person(string name, int age, string gender)
            {
                this.name = name;
                this.age = age;
                this.gender = gender;
            }
            public void SayHi()
            {
                Console.WriteLine("大家好,我是{0},今年{1}岁了。",this.name,this.age);
            }
        }
    }




    新建一个控制台项目AssemblyDemo,将MyAssembly.dll复制到控制台bin/debug下,接下来通过动态加载程序集MyAssembly.dll获取该程序集下person类的属性和方法。代码如下:



    复制代码 代码如下:
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.IO;
    using System.Reflection;


    namespace AssemblyDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                //通过反射动态调用另一个程序集中的方法
                //1加载程序集
                string path = AppDomain.CurrentDomain.BaseDirectory;//获取当前.exe执行文件的路径
                path = Path.Combine(path, "MyAssembly.dll");//拼接程序集的路径
                Assembly assembly = Assembly.LoadFile(path);
                //2创建Person类的对象
                Type type = assembly.GetType("MyAssembly.Person");
                object o = Activator.CreateInstance(type,"wolf",22,"未知");//实例化
                //3获取方法的类型
                MethodInfo methodInfo = type.GetMethod("SayHi");
                //4反射调用方法
                methodInfo.Invoke(o, null);
                Console.Read();
            }
        }
    }



    结果:


    ========

    C# 应用程序域和程序集

    http://blog.csdn.net/zhulongxi/article/details/51612233
    一、进程Process:
        进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。进程之间是相对独立的,一个进程无法直接访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他进程的运行,Windows系统就是利用进程把工作划分为多个独立的区域的。进程可以理解为一个程序的基本边界。
    1.进程的建立与销毁:
    [csharp] view plain copy
    static void Main(string[] args)  
             {  
                 Process process = Process.Start("notepad.exe","File.txt");  
                 Thread.Sleep(2000);  
                 process.Kill();  
            }  
    2.例出计算机运行中的进程:
    [csharp] view plain copy
    static void Main(string[] args)  
             {  
                var processList = Process.GetProcesses()  
                     .OrderBy(x=>x.Id)  
                    .Take(10);  
                 foreach (var process in processList)  
                    Console.WriteLine(string.Format("ProcessId is:{0} \t ProcessName is:{1}",  
                         process.Id, process.ProcessName));  
                 Console.ReadKey();  
            }  
    可以通过 GetProcessById 方法获取对应的进程,也可能通过GetProcessByName方法获取多个对应名称的进程
    3.获取进程中的所有模块module:这些模块可以是以 *.dll 结尾的程序集,也可以是 *.exe 结尾的可执行程序
    [csharp] view plain copy
    static void Main(string[] args)  
            {  
               var moduleList = Process.GetCurrentProcess().Modules;  
                foreach (System.Diagnostics.ProcessModule module in moduleList)  
                    Console.WriteLine(string.Format("{0}\n  URL:{1}\n  Version:{2}",  
                        module.ModuleName,module.FileName,module.FileVersionInfo.FileVersion));  
               Console.ReadKey();  
            }  


    二、程序集:
    1.定义:程序集是包含一个或多个类型定义文件和资源文件的集合。它允许我们分离可重用类型的逻辑表示和物理表示。
    2.功能:
    2.1.包含公共语言运行库执行的代码,如果可移植可执行 (PE) 文件没有相关联的程序集清单,则将不执行该文件中的 Microsoft 中间语言 (MSIL) 代码。请注意,每个程序集只能有一个入口点(即 DllMain、WinMain 或 Main)。
    2.2.程序集形成安全边界。程序集就是在其中请求和授予权限的单元
    2.3.程序集形成类型边界。每一类型的标识均包括该类型所驻留的程序集的名称。在一个程序集范围内加载的 MyType 类型不同于在其他程序集范围内加载的 MyType 类型。
    2.4.程序集形成引用范围边界。程序集的清单包含用于解析类型和满足资源请求的程序集元数据。它指定在该程序集之外公开的类型和资源。该清单还枚举它所依赖的其他程序集。
    2.5.程序集形成版本边界。程序集是公共语言运行库中最小的可版本化单元,同一程序集中的所有类型和资源均会被版本化为一个单元。程序集的清单描述您为任何依赖项程序集所指定的版本依赖性。
    2.6.程序集形成部署单元。当一个应用程序启动时,只有该应用程序最初调用的程序集必须存在。其他程序集(例如本地化资源和包含实用工具类的程序集)可以按需检索。这就使应用程序在第一次下载时保持精简。
    2.7.程序集是支持并行执行的单元.
        程序集可以是静态的或动态的。静态程序集可以包括 .NET Framework 类型(接口和类),以及该程序集的资源(位图、JPEG 文件、资源文件等)。静态程序集存储在磁盘上的可移植可执行 (PE) 文件中。您还可以使用 .NET Framework 来创建动态程序集,动态程序集直接从内存运行并且在执行前不存储到磁盘上。您可以在执行动态程序集后将它们保存在磁盘上。
        有几种创建程序集的方法。您可以使用过去用来创建 .dll 或 .exe 文件的开发工具,例如 Visual Studio .NET。您可以使用在 .NET Framework SDK 中提供的工具来创建带有在其他开发环境中创建的模块的程序集。您还可以使用公共语言运行库 API(例如 Reflection.Emit)来创建动态程序集。


    3.全局程序集缓存:
         安装有公共语言运行时的每台计算机都具有称为全局程序集缓存的计算机范围内的代码缓存。 全局程序集缓存中存储了专门指定给由计算机中若干应用程序共享的程序集。
        应当仅在需要时才将程序集安装到全局程序集缓存中以进行共享。 一般原则是:程序集依赖项保持专用,并在应用程序目录中定位程序集,除非明确要求共享程序集。 另外,不必为了使 COM 互操作或非托管代码可以访问程序集而将程序集安装到全局程序集缓存
       有两种方法可以将程序集部署到全局程序集缓存中:
        a. 使用专用于全局程序集缓存的安装程序。 该方法是将程序集安装到全局程序集缓存的首选方法。
         b.使用 Windows 软件开发包 (SDK) 提供的名为全局程序集缓存工具 (Gacutil.exe) 的开发工具。
    三、应用程序域:
        使用.NET建立的可执行程序 *.exe,并没有直接承载到进程当中,而是承载到应用程序域(AppDomain)当中.应用程序域是.NET引入的一个新概念,它比进程所占用的资源要少,可以被看作是一个轻量级的进程。
        在一个进程中可以包含多个应用程序域,一个应用程序域可以装载一个可执行程序(*.exe)或者多个程序集(*.dll),这样可以使应用程序域之间实现深度隔离,即使进程中的某个应用程序域出现错误,也不会影响其他应用程序域的正常运作。
        当一个程序集同时被多个应用程序域调用时,会出现两种情况:
        第一种情况:CLR分别为不同的应用程序域加载此程序集。
        第二种情况:CLR把此程序集加载到所有的应用程序域之外,并实现程序集共享,此情况比较特殊,被称作为Domain Neutral.


    1.创建自定义的应用程序域:
        当需要应用程序域时,公共语言运行时宿主会自动创建它们。 不过,您可以创建自己的应用程序域并将它们加载到需要亲自管理的程序集中。 您也可以创建从中http://write.blog.csdn.net/postedit?type=edit执行代码的应用程序域。
    [csharp] view plain copy
    namespace AttributeTest  
    {  
        class Program  
        {  
            static void Main(string[] args)  
            {  
                Console.WriteLine("Create new domain");  
                AppDomain domain = AppDomain.CreateDomain("MyDomain");  
                Console.WriteLine("Host domain: "+AppDomain.CurrentDomain.FriendlyName);//Host domain: AttributeTest.vshost.exe  
                Console.WriteLine("Child domain:"+domain.FriendlyName);// Child domain: MyDomain  
                Console.ReadKey();  
            }  
      
        }  
    }  


    2.卸载应用程序域:
        当您完成使用应用程序域时,可使用 System.AppDomain.Unload 方法将其卸载。 Unload 方法会正常关闭指定的应用程序域。 卸载过程中,没有新线程可以访问该应用程序域,并且会释放该应用程序域特定的所有数据结构。加载到应用程序域中的所有程序集都会被移除,无法再使用,如果应用程序域中的程序集不是特定于域的,则程序集的数据会保留在内存中,直到整个进程关闭。除了关闭整个进程,没有机制可以卸载非特定于域的程序集。 在某些情况下,卸载应用程序域的请求不起作用,并导致 CannotUnloadAppDomainException。
    [csharp] view plain copy
    Console.WriteLine("Creating new AppDomain.");  
       AppDomain domain = AppDomain.CreateDomain("MyDomain", null);  
      
       Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);  
       Console.WriteLine("child domain: " + domain.FriendlyName);  
       AppDomain.Unload(domain);  
       try  
       {  
           Console.WriteLine();  
           Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);  
           // The following statement creates an exception because the domain no longer exists.  
           Console.WriteLine("child domain: " + domain.FriendlyName);  
       }  
       catch (AppDomainUnloadedException e)  
       {  
           Console.WriteLine(e.GetType().FullName);  
           Console.WriteLine("The appdomain MyDomain does not exist.");  
       }  
       Console.ReadKey();  
    3.配置应用程序域:
        可以使用 AppDomainSetup 类为新的应用程序域提供带有配置信息的公共语言运行时,AppDomainSetup的ApplicationBase属性定义应用程序的根目录,当CLR需要满足类型请求时,
    它在ApplicationBase属性指定的目录中探测包含该类型的程序集。
    [csharp] view plain copy
    AppDomainSetup domainInfo = new AppDomainSetup();  
    domainInfo.ApplicationBase = "C:\Users\v-lozhu\Documents\Visual Studio 2015\Projects\MyTestProjects\AttributeTest";  
    AppDomain domain = AppDomain.CreateDomain("MyDomain",null,domainInfo);  
      
    Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);  
    Console.WriteLine("child domain: " + domain.FriendlyName);  
    Console.WriteLine("Application base is: " + domain.SetupInformation.ApplicationBase);  
    // Unload the application domain.  
    Console.ReadKey();  
    4.将程序集加载到应用程序域中:
    加载程序集到应用程序域中的方式:
    a.Assembly.Load(assemblyName);使用程序集名来加载到应用程序域中,为常用方法。
    b.Assembly.LoadFrom():加载给定其文件位置的程序集,通过此方法加载程序集将使用不同的加载上下文。
    c.Assembly.ReflectionOnlyLoad和 Assembly.ReflectionOnlyLoadFrom:将程序集加载到仅反射上下文中,可检查(但不能执行)加载到该上下文中的程序集,同时允许检查以其他平台为目标的程序集。
    d.AppDomain的CreateInstance和CreateInstanceAndUnwrap方法。
    e.Type.GetType()加载程序集
    f.AppDomain的Load方法加载程序集。主要用于实现COM互操作性,不应该使用该方法将程序集加载到除从其调用该方法的应用程序域以外的其他应用程序域。
    [csharp] view plain copy
    namespace AttributeTest  
    {  
        class Program  
        {  
            static void Main(string[] args)  
            {  
                Assembly a = <strong>Assembly.Load</strong>("ExampleTest.exe");  
                Type myType = a.GetType("ExampleTest.Example");//Name = "Example" FullName = "ExampleTest.Example"  
                MethodInfo myMethod = myType.GetMethod("MethodA");  
                object obj = Activator.CreateInstance(myType);  
                myMethod.Invoke(obj, null);  
                Console.ReadKey();  
            }  
      
        }  
    }  
    [csharp] view plain copy
    static void Main(string[] args)  
            {  
               var appDomain = AppDomain.CreateDomain("NewAppDomain");  
                <strong>appDomain.Load</strong>("Model");  
                foreach (var assembly in appDomain.GetAssemblies())  
                    Console.WriteLine(string.Format("{0}\n----------------------------",  
                       assembly.FullName));  
                Console.ReadKey();  
            }  
    /<p>//当需要在AppDomain加载可执行程序时,可以使用ExecuteAssembly方法。</p>AppDomain.ExecuteAssembly("Example.exe")  


    [csharp] view plain copy
    static void Main(string[] args)  
     {  
       var person = (Person<strong>)AppDomain.CurrentDomain.CreateInstance</strong>("Model", "Model.Person").Unwrap();  
         person.ID = 1;  
         person.Name = "ddd";  
         person.Age = 29;  
         Console.WriteLine(person.Name);  
         Console.ReadKey();  
     }  




    5.从程序集中获得类型和成员信息:
    [csharp] view plain copy
    Type MyType = Type.GetType("System.IO.BinaryReader");  
    MemberInfo[] infos = MyType.GetMembers(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);  
    Console.WriteLine("members count "+infos.Length);  
    Console.WriteLine("full name "+MyType.FullName);  
    foreach (MemberInfo item in infos)  
    {  
        Console.WriteLine("\n"+item.Name);  
    }  
    Console.ReadKey();  


    6.影像复制程序集:
        公共语言运行时会在加载程序集时锁定程序集文件,因此只有卸载此应用程序域才能更新此程序集,借助卷影复制,无需卸载应用程序域就可更新用于此应用程序域的程序集。
        应用程序域被配置为卷影复制时,应用程序路径中的程序集复制到了另一个位置,并从此位置加载,此副本处于锁定状态,但原始程序集文件已解锁并可进行更新。
        只有存储在应用程序目录或其子目录中的程序集才可进行卷影复制,这些程序集在配置应用程序域时由 ApplicationBase 和 PrivateBinPath 指定。 存储在全局程序集缓存中的程序集不可进行卷影复制。
    6.1.启用卷影复制:
    [csharp] view plain copy
    AppDomainSetup domainInfo = new AppDomainSetup();  
    domainInfo.ShadowCopyFiles = "true";  


    四、.NET 上下文Context:
        1.应用程序域是进程中承载程序集的逻辑分区,在应用程序域中存在更细粒度的用于承载.NET对象的实体,即.NET上下文Context.所有的.NET对象都存在于.NET上下文当中,每个AppDomain当中至少存在一个默认上下文(context0),:一般类所建立的对象为上下文灵活对象(context-agile),它们都由CLR自动管理,可存在于任意的上下文当中。
                        
    2.透明代理:
        在上下文的接口当中存在着一个消息接收器负责检测拦截和处理信息,当对象是MarshalByRefObject的子类的时候,CLR将会建立透明代理,实现对象与消息之间的转换。
        应用程序域是CLR中资源的边界,一般情况下,应用程序域中的对象不能被外界的对象所访问。而MarshalByRefObject 的功能就是允许在支持远程处理的应用程序中跨应用程序域边界访问对象,在使用.NET Remoting远程对象开发时经常使用到的一个父类。
    3.上下文绑定:
        当系统需要对象使用消息接收器机制的时候,即可使用ContextBoundObject类。ContextBoundObject继承了MarshalByRefObject类,保证了它的子类都会通过透明代理被访问。
        一般类所建立的对象为上下文灵活对象(context-agile),它们都由CLR自动管理,可存在于任意的上下文当中。而 ContextBoundObject 的子类所建立的对象(称作上下文绑定对象)只能在建立它的对应上下文中正常运行,此状态被称为上下文绑定。其他对象想要访问ContextBoundObject 的子类对象时,都只能通过代透明理来操作。ContextBound还有一个Synchronization特性,此特性会保证ContextBound对象被加载到一个线程安全的上下文当中运行
    [csharp] view plain copy
    class Program  
       {  
           static void Main(string[] args)  
           {  
               Example example = new Example();  
               example.Test();  
               MycontextBound bouind = new MycontextBound();  
               bouind.Test("ContextBound Test");  
               example.Sync(bouind);  
               Console.ReadKey();  
           }  
      
           public class Example  
           {  
               public void Test()  
               {  
                   ContextMessage("Example test\n");  
               }  
               public void Sync(<strong>MycontextBound contextBound</strong>)//传入MyContextBound的代理  
               {  
                   contextBound.Test("Example call on ContextBound\n");  
               }  
           }  
      
           [Synchronization]  
           public class MycontextBound : ContextBoundObject  
           {  
               public void Test(string message)  
               {  
                   ContextMessage(message);  
               }  
           }  
      
           //显示上下文信息  
           public static void ContextMessage(string data)  
           {  
               Context context = Thread.CurrentContext;  
               Console.WriteLine(string.Format("{0}ContextId is {1}", data, context.ContextID));  
               foreach (var prop in context.ContextProperties)  
                   Console.WriteLine(prop.Name);  
               Console.WriteLine();  
           }  
      
       }  
    如果在Example类中直接用MycontextBound的示例调用其test方法, 则无法调用,只能通过代理来访问MycontextBound对象。


    五、进程、线程、AppDomain、.NET上下文的关系:
    1.跨AppDomain运行代码:
        在应用程序域之间的数据是相对独立的,当需要在其他AppDomain当中执行当前AppDomain中的程序集代码时,可以使用CrossAppDomainDelegate委托。把CrossAppDomainDelegate委托绑定方法以后,通过AppDomain的DoCallBack方法即可执行委托.
    [csharp] view plain copy
    class Program  
       {  
           static void Main(string[] args)  
           {  
               Console.WriteLine("CurrentAppDomain start!");  
               //建立新的应用程序域对象  
               AppDomain newAppDomain = AppDomain.CreateDomain("newAppDomain");  
               CrossAppDomainDelegate crossAppDomainDelegate = new CrossAppDomainDelegate(MyCallBack);  
      
               newAppDomain.DoCallBack(crossAppDomainDelegate);  
      
               newAppDomain.DomainUnload += (obj, e) =>  
               {  
                   Console.WriteLine("New Domain unload!");  
               };  
      
               AppDomain.Unload(newAppDomain);  
               Console.ReadKey();  
      
           }  
           static public void MyCallBack()  
           {  
               string name = AppDomain.CurrentDomain.FriendlyName;  
               for (int n = 0; n < 4; n++)  
                   Console.WriteLine(string.Format("  Do work in {0}........", name));  
           }  
       }  
    2.跨AppDomain的线程:
        线程存在于进程当中,它在不同的时刻可以运行于多个不同的AppDomain当中。它是进程中的基本执行单元,在进程入口执行的第一个线程被视为这个进程的主线程。在.NET应用程序中,都是以Main()方法作为入口的,当调用此方法时 系统就会自动创建一个主线程。线程主要是由CPU寄存器、调用栈和线程本地存储器(Thread Local Storage,TLS)组成的。CPU寄存器主要记录当前所执行线程的状态,调用栈主要用于维护线程所调用到的内存与数据,TLS主要用于存放线程的状态信息。
        首先建立一个ConsoleApplication项目,在执行时输入当前线程及应用程序域的信息,最后生成Example.exe的可执行程序。
    [csharp] view plain copy
    class Program  
        {  
            static void Main(string[] args)  
            {  
                var message = string.Format("  CurrentThreadID is:{0}\tAppDomainID is:{1}",  
                    Thread.CurrentThread.ManagedThreadId, AppDomain.CurrentDomain.Id);  
                Console.WriteLine(message);  
                Console.Read();  
            }  
        }  
     然后再新建一个ConsoleApplication项目,在此项目中新一个AppDomain对象,在新的AppDomain中通过ExecuteAssembly方法执行Example.exe程序。(将Example生成的bin目录下的文件放到当前项目bin目录下):
    [csharp] view plain copy
    class Program  
       {  
           static void Main(string[] args)  
           {  
               Console.WriteLine("Current Appdomain start!");  
               ShowMessage();  
               //建立新的应用程序域对象  
               AppDomain newAppDomain = AppDomain.CreateDomain("newAppDomain");  
               newAppDomain.ExecuteAssembly("Example.exe");  
               AppDomain.Unload(newAppDomain);  
               Console.ReadKey();  
           }  
      
           public static void ShowMessage()  
           {  
               var message = string.Format("  CurrentThreadID is:{0}\tAppDomainID is:{1}",  
                   Thread.CurrentThread.ManagedThreadId, AppDomain.CurrentDomain.Id);  
               Console.WriteLine(message);  
           }  
       }  
    输出:
     Current Appdomain start!
      CurrentThreadID is:8  AppDomainID is:1
      CurrentThreadID is:8  AppDomainID is:2
    ID等于8的线程在不同时间内分别运行于AppDomain 1与AppDomain 2当中。
    4.3.跨上下文的线程:
    线程既然能够跨越AppDomain的边界,当然也能跨越不同的上下文。下例,线程将同时运行在默认上下文与提供安全线程的上下文中。
    [csharp] view plain copy
    class Program  
        {  
            static void Main(string[] args)  
            {  
                //当前应用程序域信息  
                Console.WriteLine("CurrentAppDomain start!");  
                ShowMessage();  
      
                //在上下文绑定对象中运行线程  
                ContextBound contextBound = new ContextBound();  
                contextBound.Test();  
                Console.ReadKey();  
            }  
      
            public static void ShowMessage()  
            {  
                var message = string.Format("  CurrentThreadID is:{0}\tAppDomainID is:{1}",  
                    Thread.CurrentThread.ManagedThreadId, Thread.CurrentContext.ContextID);  
                Console.WriteLine(message);  
            }  
      
            [Synchronization]  
            public class ContextBound : ContextBoundObject  
            {  
                public void Test()  
                {  
                    ShowMessage();  
                }  
            }  
        }  
    输出:
      CurrentAppDomain start!
      CurrentThreadID is:10 AppDomainID is:0
      CurrentThreadID is:10 AppDomainID is:1


         进程(Process)、线程(Thread)、应用程序域(AppDomain)、上下文(Context)的关系如图5.0,一个进程内可以包括多个应用程序域,也有包括多个线程,线程也可以穿梭于多个应用程序域当中。但在同一个时刻,线程只会处于一个应用程序域内。线程也能穿梭于多个上下文当中,进行对象的调用
    ========

    C#中的程序集和命名空间

    如果说命名空间是类库的逻辑组织形式,那么程序集就是类库的物理组织形式。只有同时指定类型所在的命名空间及实现该类型的程序集,才能完全限定该类型。《精通.NET核心技术--原理与架构》 程序集和命名空间不存在必然联系,一个程序集可以包含多个命名空间,同一个命名空间也可以分放在几个程序集。


    程序集是应用程序的部署单元。.NET应用程序包含一个或多个程序集。通常扩展名是EXE或DLL 的.NET可执行程序称为程序集。.NET程序集包含元数据,这些元数据描述了程序集中定义的所有类型及其成员的信息,即方法、属性、事件和字段。


    在使用共享程序集时,几个应用程序都使用同一个程序集,且与它有一定的依赖关系。共享程序集减少了磁盘和内存空间的需求。使用共享程序集时,要遵循许多规则。共享程序集必须有一个版本号和一个唯一的名称,通常它安装在全局程序集缓存(globd assembly cache,GAC,中。GAC允许共享系统上同一个程序集的不同版本。


    在一个程序集中可以有不同的名称空间,同一个名称空间也可以分布在多个程序集上。名称空间只是类型名的一种扩展,它属于类型名的范畴。


    还可以这样理解:命名空间就是一个程序集内相关类型的一个分组。举例来讲,System.IO命名空间包含了有关文件I/O的类型,System.Data命名空间定义了基本的数据库类型,等等。需要特别指出的是,一个程序集(比如mscorlib.dll)可以包含任意个命名空间,每个命名空间又可以包含多种类型。


    更好的理解程序集和命名空间的关系,可以打开VS里的对象浏览器,可以看到大量的程序集,程序集里又包含了很多不同名的命名空间,同时可以看到一个现象:不同的程序集又包含了同名的命名空间。  


    ===========================================


    命名空间与装配件的关系
    很多人对这个概念可能还是很不清晰,对于合格的.Net程序员,有必要对这点进行澄清。 装配件是.Net应用程序执行的最小单位,编译出来的.dll、.exe都是装配件。        
    装配件和命名空间的关系不是一一对应,也不互相包含,一个装配件里面可以有多个命名空间,一个命名空间也可以在多个装配件中存在,这样说可能有点模糊,举个例子:


    装配件A: 
    namespace  N1
    {
          public  class  AC1  {…}
          public  class  AC2  {…}
    }
    namespace  N2
    {
          public  class  AC3  {…}
          public  class  AC4  {…}
    }


    装配件B:


    namespace  N1
    {
          public  class  BC1  {…}
          public  class  BC2  {…}
    }
    namespace  N2
    {
          public  class  BC3  {…}
          public  class  BC4  {…}
    }


    这两个装配件中都有N1和N2两个命名空间,而且各声明了两个类,这样是完全可以的,然后我们在一个应用程序中引用装配件A,那么在这个应用程序中,我们能看到N1下面的类为AC1和AC2,N2下面的类为AC3和AC4。  


    接着我们去掉对A的引用,加上对B的引用,那么我们在这个应用程序下能看到的N1下面的类变成了BC1和BC2,N2下面也一样。        
    如果我们同时引用这两个装配件,那么N1下面我们就能看到四个类:AC1、AC2、BC1和BC2。    


    到这里,我们可以清楚一个概念了,命名空间只是说明一个类型是那个族的,比如有人是汉族、有人是回族;而装配件表明一个类型住在哪里,比如有人住在北京、有人住在上海;那么北京有汉族人,也有回族人,上海有汉族人,也有回族人,这是不矛盾的。
    ========

    程序集与反射技术(C#)

           首先我们来看程序集,程序集是代码进行编译是的一个逻辑单元,把相关的代码和类型进行组合,然后生成PE文件(例如可执行文件.exe和类库文件.dll)。由于程序集在编译后并不一定会生成单个文件,而可能会生成多个物理文件,甚至可能会生成分布在不同位置的多个物理文件,所以程序集是一个逻辑单元,而不是一个物理单元。即程序集在逻辑上是一个编译单元,但在物理储存上可以有多种存在形式。对于静态程序集可以生成单个或多个文件,而动态程序集是存在于内存中的。在C#中程序集处处可见,因为任何基于.NET的代码在编译时都至少存在一个程序集(所有.NET项目都会默认引用mscorlib程序集)。


            基于.NET框架的.dll库是一个完整的程序集,需要事先引用对应的类库。从代码的结构上看,一个程序集可以包含一个或多个命名空间,而每个命名空间中又可以包含子命名空间或类型列表。由于程序集在编译后可以生成多个模块文件,因此一个物理文件并不代表它就是一个程序集,一个程序集并不一定只有一个文件。不过,在VS开发环境中,一个解决方案可以包含多个项目,而每个项目就是一个程序集。


          程序集信息其实是通过在程序集上应用各种Attribute来设置的,并且这些特性都位于System.Reflection命名空间,也就是这一系列Attribute提供给反射技术,可用于获取程序集的基本信息.


           应用程序结构分为应用程序域—程序集—模块—类型—成员几个层次,公共语言运行库加载器管理应用程序域,这种管理包括将每个程序集加载到相应的应用程序域以及控制每个程序集中类型层次结构的内存布局。 
            程序集包含模块,而模块包含类型,类型又包含成员,反射则提供了封装程序集、模块和类型的对象。我们可以使用反射动态地创建类型的实例,将类型绑定到现有对象或从现有对象中获取类型,然后调用类型的方法或访问其字段和属性。反射通常具有以下用途。 
    (1)使用Assembly定义和加载程序集,加载在程序集清单中列出模块,以及从此程序集中查找类型并创建该类型的实例。 
    (2)使用Module了解包含模块的程序集以及模块中的类等,还可以获取在模块上定义的所有全局方法或其他特定的非全局方法。 
    (3)使用ConstructorInfo了解构造函数的名称、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetConstructors或GetConstructor方法来调用特定的构造函数。 
    (4)使用MethodInfo了解方法的名称、返回类型、参数、访问修饰符(如pulic 或private)和实现详细信息(如abstract或virtual)等。使用Type的GetMethods或GetMethod方法来调用特定的方法。 
    (5)使用FiedInfo了解字段的名称、访问修饰符(如public或private)和实现详细信息(如static)等,并获取或设置字段值。 
    (6)使用EventInfo了解事件的名称、事件处理程序数据类型、自定义属性、声明类型和反射类型等,添加或移除事件处理程序。 
    (7)使用PropertyInfo了解属性的名称、数据类型、声明类型、反射类型和只读或可写状态等,获取或设置属性值。


    (8)使用ParameterInfo了解参数的名称、数据类型、是输入参数还是输出参数,以及参数在方法签名中的位置等。 



    动态加载程序集:


    (1)通过程序集的长名称加载,一般用于加载位于全局程序集缓存中的程序集。(.NET框架的类库都位于全局程序集缓存中)(使用GacUtil命令行工具可以获取System程序集的长名称);


    (2)通过指定的文件加载程序集,通常是.dll或.exe文件。


    例如:本人的计算机上的全局程序集缓存包含下列程序集:


    system, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL
    system, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL


    项目数 = 2



          反射(Reflection)是.NET中的重要机制,通过反射,可以在运行时获得.NET中每一个类型(包括类、结构、委托、接口和枚举等)的成员,包括方法、属性、事件,以及构造函数等。还可以获得每个成员的名称、限定符和参数等。有了反射,即可对每一个类型了如指掌。如果获得了构造函数的信息,即可直接创建对象,即使这个对象的类型在编译时还不知道。


    1)反射用于获取类型信息。下面一个例子:


    复制代码
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Reflection;
     7 
     8 namespace My
     9 {
    10     class Program
    11     {
    12         static void Main(string[] args)
    13         {
    14             // 加载程序集
    15             Assembly ass = Assembly.Load("system.windows.forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
    16             // 获取Button类的Type
    17             Type typeofButton = ass.GetType("System.Windows.Forms.Button", false);
    18             if (typeofButton != null)
    19             {
    20                 // 获得Button类型的公共属性列表
    21                 PropertyInfo[] props = typeofButton.GetProperties();
    22                 // 输出属性信息
    23                 Console.WriteLine("\n  Button类的公共属性列表:");
    24                 foreach (PropertyInfo p in props)
    25                 {
    26                     Console.WriteLine("  属性名:{0},属性类型:{1}", p.Name, p.PropertyType.Name);
    27                 }
    28                 // 获取Button类型的公共事件列表
    29                 EventInfo[] events = typeofButton.GetEvents();
    30                 // 输出事件信息
    31                 Console.WriteLine("\n  Button类的公共事件列表:");
    32                 foreach (EventInfo ev in events)
    33                 {
    34                     Console.WriteLine("  事件名:{0},事件类型:{1}", ev.Name, ev.EventHandlerType.Name);
    35                 }
    36             }
    37             Console.Read();
    38        }
    39     }
    40 }
    复制代码
    2)反射还可以在运行阶段动态创建类型实例,然后就可以动态调用实例的成员。

    动态创建实例有两种方法可以选择:

    第一种:使用Activator类的CreateInstance静态方法,其中方法返回的对象就是对应的实例引用。


    看个例子:


    复制代码
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Reflection;


    namespace Me
    {
        class Program
        {
            static void Main(string[] args)
            {
                // 从当前执行的程序集中获取Test类型的Type
                Assembly ass = Assembly.GetExecutingAssembly();
                Type tp = ass.GetType("Me.Test", false);
                if (tp != null)
                {
                    // 创建实例
                    object instance = Activator.CreateInstance(tp, 105);
                    if (instance != null)
                    {
                        // 获取实例的公共属性
                        PropertyInfo[] props = tp.GetProperties(BindingFlags.Public | BindingFlags.Instance);
                        // 显示属性信息
                        foreach (var p in props)
                        {
                            Console.WriteLine("{0} : {1}", p.Name, p.GetValue(instance));
                        }
                    }
                }


                Console.Read();
            }
        }
        public class Test
        {
            public int NumValue { get; private set; }


            public Test(int sead)
            {
                Random rand = new Random(sead);
                NumValue = rand.Next();
            }
        }
    }
    复制代码
    第二种:通过反射找出类型的构造函数,然后调用构造函数来获取实例引用。


    代码如下:

    复制代码
     1 using System;
     2 using System.Collections.Generic;
     3 using System.Linq;
     4 using System.Text;
     5 using System.Threading.Tasks;
     6 using System.Reflection;
     7 
     8 namespace My
     9 {
    10     class Program
    11     {
    12         static void Main(string[] args)
    13         {
    14             // 从mscorlib程序集中获取DateTime结构的Type
    15             Type tpdatetime = Type.GetType("System.DateTime", false);
    16             if (tpdatetime != null)
    17             {
    18                 // 获取具有六个参数的构造函数
    19                 ConstructorInfo constructor = tpdatetime.GetConstructor(new Type[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) });
    20                 if (constructor != null)
    21                 {
    22                     // 调用构造函数创建实例
    23                     object instance = constructor.Invoke(new object[] { 2015, 9, 27, 13, 25, 27 });
    24                     // 获取实例的属性列表
    25                     if (instance != null)
    26                     {
    27                         PropertyInfo[] props = tpdatetime.GetProperties(BindingFlags.Public | BindingFlags.Instance);
    28                         Console.WriteLine("以下是DateTime实例的属性值列表:");
    29                         foreach (PropertyInfo p in props)
    30                         {
    31                             // 获取属性值
    32                             object objval = p.GetValue(instance);
    33                             // 显示属性名称与属性值
    34                             Console.WriteLine("{0,-15} :{1}", p.Name, objval ?? string.Empty);
    35                         }
    36                     }
    37                 }
    38             }
    39 
    40             Console.Read();
    41         }
    42     }
    43 }

    ========
    更多相关内容
  • 我试图在C#Windows窗体应用程序(Visual Studio 2005)中运行一些单元测试,但出现以下错误: System.IO.FileLoadException:无法加载文件或

    我试图在C#Windows窗体应用程序(Visual Studio 2005)中运行一些单元测试,但出现以下错误:

    System.IO.FileLoadException:无法加载文件或程序集“实用程序,版本= 1.2.0.200,区域性=中性,PublicKeyToken = 764d581291d764f7”或其依赖项之一。 找到的程序集的清单定义与程序集引用不匹配。 (HRESULT的异常:0x80131040)**

    在x.Foo.FooGO()

    在Foo.cs:第123行的x.Foo.Foo2(String groupName_)

    在FooTests.cs中的x.Foo.UnitTests.FooTests.TestFoo():行98 **

    System.IO.FileLoadException:无法加载文件或程序集“实用程序,版本= 1.2.0.203,区域性=中性,PublicKeyToken = 764d581291d764f7”或其依赖项之一。 找到的程序集的清单定义与程序集引用不匹配。 (来自HRESULT的异常:0x80131040)

    我查看了自己的参考文献,并且仅参考了Utility version 1.2.0.203 (另一个是旧的)。

    关于我如何找出试图引用此DLL文件旧版本的任何建议?

    此外,我认为我的硬盘上甚至没有这个旧程序集。 有什么工具可以搜索这个旧版本的程序集吗?


    #1楼

    我的问题是将源代码复制到新计算机上,而没有移出任何引用的程序集。

    我没有解决该错误,因此,我急忙删除了BIN目录。 重建了我的源代码,从此以后一直有效。


    #2楼

    我只是找到了收到此错误的另一个原因。 我从特定库的所有版本中清除了GAC,并参考与可执行文件一起部署的特定版本来构建我的项目。 运行项目时,出现此异常,正在搜索库的较新版本。

    原因是发布者的政策 。 当我从GAC卸载库的版本时,我也忘记了卸载发布者策略程序集,因此,程序加载器没有使用本地部署的程序集,而是在GAC中找到了发布者策略,该策略要求它搜索新版本。


    #3楼

    我的app.config包含一个

    <bindingRedirect oldVersion="1.0.0.0" newVersion="2.0.11.0"/>
    

    对于npgsql。 以某种方式在用户计算机上,我的app.exe.config丢失了。 我不确定这是一个愚蠢的用户,安装程序出现故障还是淘汰了防病毒软件。 替换文件解决了该问题。


    #4楼

    以下内容将所有程序集版本重定向到版本3.1.0.0。 我们有一个脚本,该脚本将始终在App.config中更新此引用,因此我们不必再处理此问题。

    通过反射,您可以获取程序集publicKeyToken并从.dll文件本身生成此块。

    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
     <dependentAssembly>
        <assemblyIdentity name="Castle.Core" publicKeyToken="407dd0808d44fbdc" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="3.1.0.0" />
      </dependentAssembly>
    </assemblyBinding>
    

    请注意,如果没有XML名称空间属性(xmlns),此功能将无效。


    #5楼

    我只是遇到了这个问题,问题是我的应用程序调试目录中有.dll的旧副本。 您可能还需要检查那里(而不是GAC)以查看是否看到它。


    #6楼

    对我来说,“ Local.testtesttings”文件中的代码覆盖率配置“引起”了问题。 我忘了更新那里引用的文件。


    #7楼

    其他答案对我不起作用。 如果您不关心版本,而只是想运行您的应用程序,则右键单击引用并将“特定版本”设置为false ...这对我有用。 在此处输入图片说明


    #8楼

    我想补充一下,我正在创建一个基本的ASP.NET MVC 4项目,并通过NuGet添加了DotNetOpenAuth.AspNet。 在我为Microsoft.Web.WebPages.OAuth引用了不匹配的DLL文件之后,这导致了相同的错误。

    为了解决这个问题,我做了一个Update-Package并清理了解决方案以进行全面重建。

    那对我有用,是一种懒惰的方式,但是时间就是金钱:-P


    #9楼

    我只是自己遇到了这个问题,而我发现这个问题与其他人遇到的问题有所不同。

    我的主项目引用了两个DLL:CompanyClasses.dll和CompanyControls.dll。 我收到运行时错误消息:

    无法加载文件或程序集'CompanyClasses,Version = 1.4.1.0,Culture = neutral,PublicKeyToken = 045746ba8544160c'或其依赖项之一。 找到的程序集的清单定义与程序集引用不匹配

    麻烦的是,我的系统上没有任何版本为1.4.1的CompanyClasses.dll文件。 GAC中没有,应用程序文件夹中没有...在任何地方都没有。 我搜索了整个硬盘。 我拥有的所有CompanyClasses.dll文件均为1.4.2。

    我发现真正的问题是CompanyControls.dll引用了CompanyClasses.dll的1.4.1版本。 我只是重新编译了CompanyControls.dll(在引用了CompanyClasses.dll 1.4.2之后),这个错误对我来说已经消失了。


    #10楼

    对于我们来说,问题是由其他原因引起的。 DevExpress组件的许可证文件包括两行,一个用于未安装在此特定计算机上的旧版本组件。 从许可证文件中删除较旧的版本可以解决此问题。

    令人讨厌的部分是,错误消息没有指出导致问题的引用。


    #11楼

    在AssemblyInfo.cs文件中的AssemblyVersion中,使用固定的版本号而不是指定*。 *将更改每次编译的版本号。 在我的情况下,这就是此异常的问题。


    #12楼

    .NET程序集加载器:

    • 找不到1.2.0.203
    • 但确实找到了1.2.0.200

    该程序集与请求的程序集不匹配,因此出现此错误。

    简而言之,它找不到所引用的程序集。 通过将其放在GAC或应用程序路径中,确保可以找到正确的程序集。 另请参阅http://blogs.msdn.com/junfeng/archive/2004/03/25/95826.aspx


    #13楼

    您可以做几件事来解决此问题。 首先,使用Windows文件搜索在硬盘驱动器中搜索程序集(.dll)。 获得结果列表后,请执行View-> Choose Details ...,然后检查“ File Version”。 这将在结果列表中显示版本号,因此您可以看到旧版本可能来自何处。

    另外,就像Lars所说的那样,检查您的GAC以查看那里列出了什么版本。 Microsoft的这篇文章指出,在构建过程中不会在本地复制在GAC中找到的程序集,因此您可能需要先删除旧版本,然后再进行全部重建。 (有关创建批处理文件的注释,请参阅我对这个问题的回答)

    如果仍然无法确定旧版本的来源,则可以使用Visual Studio附带的fuslogvw.exe应用程序来获取有关绑定失败的更多信息。 Microsoft 在此处提供了有关此工具的信息 。 请注意,您必须通过将HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Fusion\\EnableLog注册表项设置为1来启用日志记录。


    #14楼

    我添加了一个NuGet包,只是意识到我的应用程序的黑盒部分是在引用该库的旧版本。

    我删除了该程序包,并引用了旧版本的静态DLL文件,但从未从以下位置更新过web.config文件:

    <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
        <bindingRedirect oldVersion="0.0.0.0-4.5.0.0" newVersion="6.0.0.0" />
    </dependentAssembly>
    

    卸载软件包时应恢复为的状态:

    <dependentAssembly>
        <assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" />
        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.5.0.0" />
    </dependentAssembly>
    

    #15楼

    从文件夹位置手动删除旧程序集,然后将引用添加到新程序集可能会有所帮助。


    #16楼

    就我而言,问题出在椅子和键盘之间:-)

    Could not load file or assembly 'DotNetOpenAuth.Core, Version=4.0.0.0,
    Culture=neutral, PublicKeyToken=2780ccd10d57b246' or one of its dependencies.
    The located assembly's manifest definition does not match the assembly reference.
    (Exception from HRESULT: 0x80131040)
    

    两个或多个不同的程序集希望使用不同版本的DotNetOpenAuth库,这不会有问题。 此外,在我的本地计算机上,NuGet自动更新了一个web.config:

    <dependentAssembly>
        <assemblyIdentity name="DotNetOpenAuth.AspNet" publicKeyToken="2780ccd10d57b246" culture="neutral" />
            <bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" />
        </dependentAssembly>
        <dependentAssembly>
            <assemblyIdentity name="DotNetOpenAuth.Core" publicKeyToken="2780ccd10d57b246" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-4.3.0.0" newVersion="4.3.0.0" />
    </dependentAssembly>
    

    然后我意识到我忘了将新的web.config复制/部署到生产服务器。 因此,如果您具有手动部署web.config的方式,请检查它是否已更新。 如果生产服务器的web.config完全不同,则必须在使用NuGet之后同步合并这些dependentAssembly部分。


    #17楼

    我遇到了同样的错误...就我而言,它如下解决:

    • 刚安装应用程序时,这里的人们在应用程序中使用了Microsoft Enterprise Library 4.1。
    • 在前一周,我的机器被格式化了,而今天之后,当我构建该应用程序时,它给了我一个错误,即企业库程序集丢失了。
    • 然后,我安装了Microsoft Enterprise Library 5.0,该产品是我在Google上获得的第一个搜索条目。
    • 然后,当我构建应用程序时,它给了我上面的错误,即所定位的程序集的清单定义与程序集引用不匹配。
    • 经过大量搜索和分析,我发现应用程序引用了4.1.0.0,而bin文件夹中的DLL是版本5.0.0.0。
    • 然后我要做的是安装了Microsoft Enterprise Library 4.1。
    • 删除了以前的参考(5.0)并添加了4.0参考。
    • 构建了应用程序,瞧……它起作用了。

    #18楼

    在Team Foundation Server的构建服务上构建时出现此错误。 事实证明,我的解决方案中有多个项目使用的是NuGet添加的同一个库的不同版本。 我使用NuGet删除了所有旧版本,并添加了新版本作为所有参考。

    Team Foundation Server将所有DLL文件放在一个目录中,当然一次只能有一个同名的DLL文件。


    #19楼

    如果您使用的是Visual Studio,请尝试“清除解决方案”,然后重新生成您的项目。


    #20楼

    如果尝试使用反射后期绑定,绑定的程序集具有强名称或更改了其公钥令牌,则会引发完全相同的错误。 即使实际上没有找到具有指定公钥令牌的程序集,该错误也是相同的。

    您需要添加正确的公共密钥令牌(可以在dll上使用sn -T来获取它)来解决该错误。 希望这可以帮助。


    #21楼

    我的情况与内森·贝德福德(Nathan Bedford)的职位非常相似,但略有不同。 我的项目也以两种方式引用了更改后的dll。 1)直接和2)通过引用本身具有对更改后的dll的引用的组件(类库)来间接实现。 现在,我的component(2)的Visual Studio项目引用了更改后的dll的正确版本。 但是,组件本身的版本号未更改。 结果,安装新版本的项目无法替换客户端计算机上的该组件。

    最终结果:直接引用(1)和间接引用(2)指向客户端计算机上已更改dll的不同版本。 在我的开发机器上,它运行良好。

    解决方法:删除应用程序; 从应用程序文件夹中删除所有DLLS; 重新安装,就像我的情况一样简单。


    #22楼

    在我的情况下,它是C:\\ WINDOWS \\ Microsoft.NET \\ Framework \\〜\\ Temporary ASP.NET Files \\目录中的DLL的旧版本。 您可以删除或替换旧版本,也可以删除并将引用添加回项目中。 基本上,任何一种方法都会创建一个指向临时ASP.NET文件的新指针。


    #23楼

    就我而言,此错误是在运行ASP.NET应用程序时发生的。 解决方案是:

    1. 删除项目文件夹中的objbin文件夹

    清理不起作用,重建不起作用,所有引用都很好,但是它不是在编写其中一个库。 删除这些目录后,一切正常。


    #24楼

    这是我解决此问题的方法。

    1. 从异常消息中,获取“问题”库的名称和“预期”版本号。

    在此处输入图片说明

    1. 在您的解决方案中找到该.dll的所有副本 ,右键单击它们,然后检查它是哪个版本的.dll。

    在此处输入图片说明

    好的,因此在此示例中,我的.dll绝对是2.0.5022.0(因此Exception版本号错误)。

    1. 搜索解决方案中所有.csproj文件中“异常”消息中显示的版本号。 将此版本号替换为dll中的实际编号。

    因此,在此示例中,我将替换它...

    <Reference Include="DocumentFormat.OpenXml, Version=2.5.5631.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
    

    ... 有了这个...

    <Reference Include="DocumentFormat.OpenXml, Version=2.0.5022.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
    

    任务完成 !


    #25楼

    只需删除项目的bin文件夹中的内容并重建解决方案即可解决我的问题。


    #26楼

    清理并重建解决方案可能不会替换输出目录中的所有dll。

    我的建议是尝试将文件夹从“ bin”重命名为“ oldbin”或将“ obj”重命名为“ oldobj”

    然后尝试重新建立您的解决方案。

    如果您使用的是第三方dll,则在成功构建后需要将其复制到新创建的“ bin”或“ obj”文件夹中。

    希望这对您有用。


    #27楼

    如果您遇到类似“ 所定位的程序集的清单定义与程序集引用不匹配类的错误,并且如果您已通过VS中的“项目”>“管理NuGet程序包和更新”选项卡进行了更新 ,那么您可以做的第一件事就是尝试安装另一个版本的从NuGet Gallery页面检查版本并从Package Manager控制台运行以下命令后,请执行以下操作:

    PM> Install-Package YourPackageName -Version YourVersionNumber 
    //Example
    PM> Install-Package Microsoft.Extensions.FileProviders.Physical -Version 2.1.0
    

    尽管答案与所讨论的软件包没有直接关系,并且已经被问到了答案,但它是通用的,仍然很相关,希望对您有所帮助。


    #28楼

    我现在要打动大家。 。 。

    从您的.config文件中删除所有<assemblyBinding>引用,然后从NuGet软件包管理器控制台中运行以下命令:

    Get-Project -All | Add-BindingRedirect
    

    #29楼

    由于引用了与我正在构建的程序集同名的程序集,因此我收到此错误消息。

    编译后,但是使用当前项目程序集覆盖了引用的程序集-从而导致错误。

    要修复它,我更改了项目的名称,并通过右键单击项目并选择“属性”来使用装配属性。


    #30楼

    我会让别人从我的愚蠢行为中受益。 我对一个完全独立的应用程序有一些依赖性(我们将此称为App1)。 该App1中的dll被拉到我的新应用程序(App2)中。 每当我在APP1中进行更新时,我都必须创建新的dll并将其复制到App2中。 好。 。 我厌倦了在2个不同的App1版本之间进行复制和粘贴的操作,因此我只是在dll的前缀中添加了“ NEW_”前缀。

    好。 。 。 我猜想构建过程会扫描/ bin文件夹,并且当它错误地匹配某些内容时,它会发出与上述相同的错误消息。 我删除了“ new_”版本,但它的构建只是花花公子。

    展开全文
  • Unity-程序集

    千次阅读 2021-11-03 09:57:54
    Unity-程序集初识 unity中程序集创建 程序集创建后包含的脚本范围为当前文件夹下所有的脚本文件,包括子目录下的文件。但是,在程序集之外建立的脚本会属于unity自己本身程序集的内容。(CShape.Dll) 默认的...

    Unity-程序集初识

    • unity中程序集创建
      在这里插入图片描述

    • 程序集创建后包含的脚本范围为当前文件夹下所有的脚本文件,包括子目录下的文件。但是,在程序集之外建立的脚本会属于unity自己本身程序集的内容。(CShape.Dll)在这里插入图片描述

    • 默认的cshape.dll下是可以调用到下面所有的dil文件的(也就是为什么dll导入Unity之后会自动识别了)
      在这里插入图片描述

    • 如果要是不是默认的dll 相互调用就需要添加依赖关系。
      在这里插入图片描述
      在这里插入图片描述

    • 在C#中使用C++代码,防止不安全代码需要勾选Allow ‘unsafe’ code(暂时没用到过,后续用到了在补充)在这里插入图片描述

    • 如果需要某些dll下的脚本文件打包发布时不被打进包里,需要勾选TestAssemblies选项
      在这里插入图片描述

    展开全文
  • 常用算法程序集(C++语言描述)第四版(徐士良),文件超过60M,所以分两部分,这是第二部分。
  • Unity添加程序集引用

    千次阅读 2020-07-27 17:10:11
    在unity中添加第三方库的时候,通过NuGet管理器安装了第三方的库,但是使用的时候提示缺少程序集,或者下载了dll文件要在程序中使用,这时候可以手动添加程序集。 1、在引用中双击任意引用,打开“对象浏览器”...

    在unity中添加第三方库的时候,通过NuGet管理器安装了第三方的库,但是使用的时候提示缺少程序集,或者下载了dll文件要在程序中使用,这时候可以手动添加程序集。

     

    1、在引用中双击任意引用,打开“对象浏览器”

    2、点击“...”符号,在打开的弹窗中,切换到“浏览”选项,然后找到程序集,选择然后确定。

    3、这时程序集就被添加到了“对象浏览器”,选择对应程序集,然后点击后面的添加。

    4、这样引用中就包含添加的程序集了,可以正常使用了。

    展开全文
  • 找到的程序集清单定义与程序集引用不匹配。 (异常来自 HRESULT:0x80131040) 文件名:“System.Runtime, Version=4.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a” 在 GaoQiManage.Web.Controllers....
  • C#问题解决: 无法加载文件或程序集

    千次阅读 2021-05-06 16:46:57
    未能加载文件或程序集“ System.Runtime.CompilerServices.Unsafe, Version=4.0.4.1, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a” 或它的某一个依赖项。系统找不到指定的文件 English Could not load file ...
  • VS 2019找不到程序集

    千次阅读 多人点赞 2021-03-09 15:50:35
    因为要下载的是2019离线版本,网速还不太好,然后安装后一用就出现问题,不是什么找不到程序集,然后不是找不到这个那个! 现在就说一下为什么在VS 2019中创建类库的时候,在引用中没有找到“程序集",或者最基本的想...
  • C#中添加程序集引用

    千次阅读 2021-06-15 19:43:03
    当我们复制别人的代码时,往往会在程序的头部using System.*;出现Using指令时不存在的。如图 提示:命名空间“System”中不存在类型或命名空间名称“Forms”(是缺少程序集引用吗?)
  • 什么是程序集

    千次阅读 2018-10-30 11:26:01
    一、 程序集定义 由.NET 编译生成的EXE文件或DLL文件就是程序集,例如:System.Data.dll。   二、 程序集结构   1. 程序集清单:和我们在淘宝买东西的配送清单一样就是说明里面包含了什么东东。 2. 类型...
  • C#未能加载文件或程序集

    千次阅读 2020-12-11 09:42:45
    编写C#代码很容易出现:未能加载或程序集“XXXX,Version=0.0.0.0,Culter=neutral,PublicKeyToken=null”的问题 1、是否添加引用 查看是否添加提示中的引用文件,如未添加,则添加该引用即可。 2、操作系统和VS的目标...
  • 警告: 程序集绑定日志记录被关闭。解决方法
  • I am currently developing a .NET application, which consists of 20 projects. 我目前正在开发一个.NET应用程序,它包含2
  • 使用visual studio时 错误 找不到 .NETFramework,Version=v4.0 的引用程序集。要解决此问题,请为此框架版本安装开发人员工具包(SDK/目标包)或者重新定向应用程序。可在 https://aka.ms/msbuild/developerpacks 处...
  • 未能找到程序集“Windows”。请检查磁盘上是否存在该程序集。 如果您的代码需要此引用,则可能出现编译错误。 1>G:\NEON\UE_424\Engine\Source\Programs\AutomationTool\HoloLens\HoloLensPlatform.Automation.cs...
  • .dll: 未能加载文件或程序集“AutomationScripts.Automation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=null”或它的某一个依赖项。不支持操作。 (异常来自 HRESULT:0x80131515) ——————————...
  • VS中给项目添加程序集引用

    千次阅读 2020-11-14 09:48:38
    直接右键“引用”添加引用,选择需要的项目或程序集 有时候“引用”上没有添加引用的选项,这时就随便选中一个已添加的引用,双击后进入“对象浏览器”,查找到需要的引用并添加就可以了 ...
  • 常用算法程序集(C++语言描述)第四版(徐士良),文件超过60M,所以分两部分,这是第一部分。
  • C# 应用程序域和程序集

    千次阅读 2016-06-08 12:10:47
     进程(Process)是Windows系统中的一个基本概念,它包含着一个运行程序所需要的资源。进程之间是相对独立的,一个进程无法直接访问另一个进程的数据(除非利用分布式计算方式),一个进程运行的失败也不会影响其他...
  • 为什么Newtonsoft.Json版本不一致? 是,项目间的生成是有序生成的,它取决于项目间的依赖顺序。...那么当我生成Web项目的时候,因为我要注册Bll程序集,所以我要先生成Bll程序集,而BLL程序集又引用了Da...
  • 写过易语言模块的都知道,我们可以建立类模块也可以建立程序集模块,那么二者有何不同,听小编总结如下。 1、同样的功能 用类模块和程序集 都可以实现。2、类的程序集变量(也称类成员)同一个变量(类型就是这个类的...
  • 原因:应用需要的dll与提供dll的.NET Framework版本不一致,比如应用需要的版本是.NET Framework2,但是本地提供的是.NET Framework 4。 可以使用ILSpy工具查看dll版本 ...
  • 报错信息:未能加载文件或程序集"Newtonsoft.Json, Version-11.0.0.0, Culture-neutral, PublicKeyToken=30ad4fe6b2a6aeed“或它的某一个依赖项。系统找不到指定的文件 原因:由于代码中需要用到Newtonsoft.Json里的...
  • 2. 强签名的库,或者应用程序只能引用强签名的dll,不能引用未强签名的dll,但是未强签名的dll可以引用强签名的dll。 3. 强签名无法保护源代码,强签名的dll是可以被反编译的。 4. 强签名的dll可以防止第三方恶意...
  • 错误:程序集绑定日志记录被关闭

    千次阅读 2020-10-09 10:52:10
    解决方法: 将IIS中的应用程序服务池中"启动32位应用程序"设置为true。
  • VS2019没有添加引用选项,不显示程序集

    万次阅读 多人点赞 2021-01-10 21:16:01
    艹 框架选错了 一天忙于 卸载_重装_找别的解决办法 结果发现框架弄错了, 查看当前类型的框架 项目右键 属性 目标框架 看你的是.core框架 还是 .net Framework 框架 前者没有引用管理器不显示程序集 后者显示 打不了...
  • 请注意,将从全局程序集缓存(GAC)解析程序集,并将使用这些程序集替换引用程序集。因此,程序集的目标可能未正确指向您所预期的框架。 非clr项目不允许设置.NETFramework ...
  • 打包成一个程序集可以避免分发程序的时候带上一堆依赖而出问题。 ILMerge 可以用来将多个程序集合并成一个程序集。本文介绍使用 ILMerge 工具和其 NuGet 工具包来合并程序集和其依赖。 本文内容以 NuGet 包的形式...
  • 解决未能加载文件或程序集xxx:“未能加载文件或程序集“xxx, Version=x.x.x.x, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”或它的某一个依赖项。系统找不到指定的文件。
  • utm_medium=referral 多层架构,在每次重新生成解决方案的时候,老是提示:warning MSB3245: 未能解析此...未能找到程序集“ ”。请检查磁盘上是否存在该程序集。 如果您的代码需要此引用,则可能出现编译错误。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,354,802
精华内容 541,920
关键字:

程序集