C# 自定义exe引用的dll路径

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 自定义exe引用的dll路径相关的知识,希望对你有一定的参考价值。

 

MSDN原文:https://msdn.microsoft.com/library/twy1dw1e(v=vs.100).aspx

<runtime> 的 <assemblyBinding> 元素

.NET Framework 4             
 
 

 

包含有关程序集版本重定向和程序集位置的信息。

 
<assemblyBinding  
   xmlns="urn:schemas-microsoft-com:asm.v1" appliesTo="v1.0.3705">
</assemblyBinding>

以下几节描述了属性、子元素和父元素。

特性

 

特性

说明

xmlns

必选特性。

指定程序集绑定所需的 XML 命名空间。  使用字符串“urn:schemas-microsoft-com:asm.v1”作为值。 

appliesTo

指定 .NET Framework 程序集重定向所应用的运行时版本。  此可选特性使用 .NET Framework 版本号指示其适用的版本。  如果没有指定 appliesTo 特性,<assemblyBinding> 元素将适用于 .NET Framework 的所有版本。  appliesTo 特性是在 .NET Framework 1.1 版中引入的;.NET Framework 1.0 版将忽略该特性。  这意味着,即使指定了 appliesTo 特性,在使用 .NET Framework 1.0 版时所有的 <assemblyBinding> 元素也都适用。 

子元素

 

元素

说明

<dependentAssembly>

封装程序集的绑定策略和程序集位置。  为每个程序集使用一个 <dependentAssembly> 标记。 

<probing>

指定加载程序集时公共语言运行时搜索的子目录。

<publisherPolicy>

指定运行时是否采用出版商策略。

<qualifyAssembly>

指定当使用程序集的部分名称时应动态加载的程序集全名。

父元素

 

元素

说明

configuration

每个配置文件中的根元素,常用语言 runtime 和 .NET Framework 应用程序会使用这些文件。

runtime

包含程序集绑定和垃圾回收的相关信息。

示例
 

下面的示例显示如何将一个程序集版本重定向到另一个版本并提供基本代码。

<configuration>
   <runtime>
      <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
         <dependentAssembly>
            <assemblyIdentity name="myAssembly"
                              publicKeyToken="32ab4ba45e0a69a1"
                              culture="neutral" />
            <bindingRedirect oldVersion="1.0.0.0"
                             newVersion="2.0.0.0"/>
            <codeBase version="2.0.0.0"
                      href="http://www.litwareinc.com/myAssembly.dll"/>
         </dependentAssembly>
      </assemblyBinding>
   </runtime>
</configuration>

下面的示例显示如何使用 appliesTo 特性重定向 .NET Framework 程序集绑定。

<runtime>
   <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1" appliesTo="v1.0.3705">
      <dependentAssembly> 
         <assemblyIdentity name="mscorcfg" publicKeyToken="b03f5f7f11d50a3a" culture=""/>
         <bindingRedirect oldVersion="0.0.0.0-65535.65535.65535.65535" newVersion="1.0.3300.0"/>
      </dependentAssembly>
   </assemblyBinding>
</runtime

exe文件和dll文件分开在不同目录,这时候可以有3种方法

1.在app.config中配置

 

 
  1. <runtime>  
  2.     <gcConcurrent enabled="true" />  
  3.     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">  
  4.       <publisherPolicy apply="yes" />  
  5.       <probing privatePath="32;64" />  
  6.     </assemblyBinding>  
  7.   </runtime>  
<runtime>
    <gcConcurrent enabled="true" />
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <publisherPolicy apply="yes" />
      <probing privatePath="32;64" />
    </assemblyBinding>
  </runtime>
2. AppDomain.CurrentDomain.AppendPrivatePath来设置

 

 

3.new AppDomainSetup().PrivateBinPath 来设置

 
  1. if (AppDomain.CurrentDomain.IsDefaultAppDomain())  
  2.  {  
  3.      string appName = AppDomain.CurrentDomain.FriendlyName;  
  4.      var currentAssembly = Assembly.GetExecutingAssembly();  
  5.      AppDomainSetup setup = new AppDomainSetup();  
  6.      setup.ApplicationBase = System.Environment.CurrentDirectory;  
  7.      setup.PrivateBinPath = "Libs";  
  8.      setup.ConfigurationFile = setup.ApplicationBase +  
  9.                          string.Format("\\\\Config\\\\{0}.config", appName);  
  10.      AppDomain newDomain = AppDomain.CreateDomain("NewAppDomain", null, setup);  
  11.      int ret = newDomain.ExecuteAssemblyByName(currentAssembly.FullName, e.Args);  
  12.      AppDomain.Unload(newDomain);  
  13.      Environment.ExitCode = ret;  
  14.      Environment.Exit(0);  
  15.      return;  
  16.  }  
           if (AppDomain.CurrentDomain.IsDefaultAppDomain())
            {
                string appName = AppDomain.CurrentDomain.FriendlyName;
                var currentAssembly = Assembly.GetExecutingAssembly();
                AppDomainSetup setup = new AppDomainSetup();
                setup.ApplicationBase = System.Environment.CurrentDirectory;
                setup.PrivateBinPath = "Libs";
                setup.ConfigurationFile = setup.ApplicationBase +
                                    string.Format("\\\\Config\\\\{0}.config", appName);
                AppDomain newDomain = AppDomain.CreateDomain("NewAppDomain", null, setup);
                int ret = newDomain.ExecuteAssemblyByName(currentAssembly.FullName, e.Args);
                AppDomain.Unload(newDomain);
                Environment.ExitCode = ret;
                Environment.Exit(0);
                return;
            }

 

可有时候又不想把他放在config文件上,只想用代码来实现,第二中方法发现已经过期,第三种方法MSDN语焉不详的,网上也没有什么资料,目前就用第四种方法

 

4.AppDomain有个AssemblyResolve事件,加载dll失败的时候触发,可以在这个事件里面处理

 

 
  1. AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;  
AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
 
  1. /// <summary>  
  2.         /// 对外解析dll失败时调用  
  3.         /// </summary>  
  4.         /// <param name="sender"></param>  
  5.         /// <param name="args"></param>  
  6.         /// <returns></returns>  
  7.         static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)  
  8.         {  
  9.             string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Libs\\");  
  10.             path = System.IO.Path.Combine(path, args.Name.Split(‘,‘)[0]);  
  11.             path = String.Format(@"{0}.dll", path);  
  12.             return System.Reflection.Assembly.LoadFrom(path);  
  13.         }  
/// <summary>
        /// 对外解析dll失败时调用
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        /// <returns></returns>
        static System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
        {
            string path = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"Libs\\");
            path = System.IO.Path.Combine(path, args.Name.Split(‘,‘)[0]);
            path = String.Format(@"{0}.dll", path);
            return System.Reflection.Assembly.LoadFrom(path);
        }

以上是关于C# 自定义exe引用的dll路径的主要内容,如果未能解决你的问题,请参考以下文章

C#的Dllimport能不能调用指定路径的dll文件?

C#中引用dll的问题

C#的Dllimport能不能调用指定路径的dll文件?

C#将DLL嵌入到exe当中

c# wpf项目中引用的dll怎么让它能自动更新?

C# winform 引用问题 引用了SHDocVw.dll。 把exe单独拷出来就报异常。 有啥方法解决?