簡體   English   中英

在探測privatePath時使用絕對路徑

[英]Using an absolute path in probing privatePath

在C#控制台應用程序中,我正在嘗試使用<probing privatePath=""/>指向不在我的應用程序子目錄中的dll。 我正在使用:

<runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
        <probing privatePath="D:\Library\References" />
    </assemblyBinding>
</runtime>    

這不起作用,因為privatePath正在我的應用程序中查找子目錄。 有沒有辦法以這種方式使用絕對路徑? 如果沒有,指向位於我的應用程序之外的dll的最佳方法是什么? 我也嘗試將<codebase>file:///路徑一起使用,但仍然有一個System.IO.FileNotFound異常。

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity 
        name="MyLibrary" publicKeyToken="29989D7A39ACF230" />
      <codeBase
        version="2.0.0.0"
        href="http://file:///D:/Library/References/NLog.dll"/>
    </dependentAssembly>
  </assemblyBinding>
</runtime>

但仍然有一個System.IO.FileNotFound異常。

謝謝!

根據MSDN

您只能在機器配置中使用該元素,或者也可以使用也重定向程序集版本的發布者策略文件 ...如果要為沒有強名稱的程序集提供代碼基礎提示,則提示必須指向應用程序庫或應用程序基目錄的子目錄。

您可能嘗試在app.config申請?

privatePath中指定的目錄必須是應用程序基目錄的子目錄。

在這種情況下使用AssemblyResolver。

這里有一些代碼我部分地從另一個問題中抄襲並修改以供我們自己使用。 與鏈接代碼不同,這個解析了應用程序執行文件夾,這是我在許多其他示例中沒有看到的。 如有必要,請隨意切除並堅持自己的絕對路徑。

程序集解析器的一個優點是,如果你有dll的混合版本,並且想要從目標文件夾加載dll,而不是那個恰好與應用程序一起加載的那個,那么這是有效的,而配置文件方法不是。

我有這個問題,因為我們的應用程序附帶了一個小應用程序,它是一個應用程序升級程序,它通常需要引用比原始應用程序更新的dll版本。 (升級程序會更新,然后升級程序會更新主應用程序。如果它們都查看相同的dll,則可能會發生錯誤。)

public static class AssemblyResolver
{
    internal static void Hook(params string[] folders)
    {
        AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
        {
            // Check if the requested assembly is part of the loaded assemblies
            var loadedAssembly = AppDomain.CurrentDomain.GetAssemblies().FirstOrDefault(a => a.FullName == args.Name);
            if (loadedAssembly != null)
                return loadedAssembly;

            // This resolver is called when a loaded control tries to load a generated XmlSerializer - We need to discard it.
            // http://connect.microsoft.com/VisualStudio/feedback/details/88566/bindingfailure-an-assembly-failed-to-load-while-using-xmlserialization

            var n = new AssemblyName(args.Name);

            if (n.Name.EndsWith(".xmlserializers", StringComparison.OrdinalIgnoreCase))
                return null;

            // http://stackoverflow.com/questions/4368201/appdomain-currentdomain-assemblyresolve-asking-for-a-appname-resources-assembl

            if (n.Name.EndsWith(".resources", StringComparison.OrdinalIgnoreCase))
                return null;

            string assy = null;
            // Get execution folder to use as base folder
            var rootFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)??"";

            // Find the corresponding assembly file
            foreach (var dir in folders)
            {
                assy = new[] { "*.dll", "*.exe" }.SelectMany(g => Directory.EnumerateFiles(Path.Combine(rootFolder,dir), g)).FirstOrDefault(f =>
                {
                    try
                    {
                        return n.Name.Equals(AssemblyName.GetAssemblyName(f).Name,
                            StringComparison.OrdinalIgnoreCase);
                    }
                    catch (BadImageFormatException)
                    {
                        return false; /* Bypass assembly is not a .net exe */
                    }
                    catch (Exception ex)
                    {
                        // Logging etc here
                        throw;
                    }
                });

                if (assy != null)
                    return Assembly.LoadFrom(assy);
            }

            // More logging for failure here
            return null;
        };
    }
}

在提供用於程序集解析的路徑列表時盡早調用此方法

AssemblyResolver.Hook("upglib","myOtherFolder");

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM