【问题标题】:how to load all assemblies from within your /bin directory如何从 /bin 目录中加载所有程序集
【发布时间】:2010-11-20 06:31:17
【问题描述】:

在 Web 应用程序中,我想加载 /bin 目录中的所有程序集。

由于它可以安装在文件系统的任何位置,我无法保证它的存储路径。

我想要一个汇编程序集对象的列表。

【问题讨论】:

    标签: c# assemblies


    【解决方案1】:

    您可以这样做,但您可能不应该像这样将所有内容加载到当前的应用程序域中,因为程序集可能包含有害代码。

    public IEnumerable<Assembly> LoadAssemblies()
    {
        DirectoryInfo directory = new DirectoryInfo(@"c:\mybinfolder");
        FileInfo[] files = directory.GetFiles("*.dll", SearchOption.TopDirectoryOnly);
    
        foreach (FileInfo file in files)
        {
            // Load the file into the application domain.
            AssemblyName assemblyName = AssemblyName.GetAssemblyName(file.FullName);
            Assembly assembly = AppDomain.CurrentDomain.Load(assemblyName);
            yield return assembly;
        } 
    
        yield break;
    }
    

    编辑:我没有测试代码(在这台计算机上无法访问 Visual Studio),但我希望你能明白。

    【讨论】:

      【解决方案2】:

      好吧,你可以自己用以下方法破解它,最初使用类似的方法:

      string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
      

      获取当前程序集的路径。接下来,使用带有合适过滤器的 Directory.GetFiles 方法遍历路径中的所有 DLL。您的最终代码应如下所示:

      List<Assembly> allAssemblies = new List<Assembly>();
      string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
      
      foreach (string dll in Directory.GetFiles(path, "*.dll"))
          allAssemblies.Add(Assembly.LoadFile(dll));
      

      请注意,我尚未对此进行测试,因此您可能需要检查 dll 是否实际包含完整路径(如果不包含则连接路径)

      【讨论】:

      • 您可能还想添加一个检查以确保您没有添加您实际运行的程序集:)
      • path变量包含目录文件名,需要用Path.GetDirectoryName(path)缩短
      • 对于我的 ASP.NET 应用程序,CodeBase 似乎包含正确的路径。使用 Uri.LocalPath 删除文件://-part。
      • 不要忘记检查“*.exe”,因为可执行文件也可以是程序集。顺便说一句,在 .NET 4+ 中枚举文件有更好的方法。看看这个问题stackoverflow.com/questions/163162/…
      【解决方案3】:

      要获取 bin 目录,string path = Assembly.GetExecutingAssembly().Location;总是有效(尤其是当正在执行的程序集已放置在 ASP.NET 临时目录中时)。

      您应该使用string binPath = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "bin");

      此外,您可能应该考虑 FileLoadException 和 BadImageFormatException。

      这是我的工作功能:

      public static void LoadAllBinDirectoryAssemblies()
      {
          string binPath = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "bin"); // note: don't use CurrentEntryAssembly or anything like that.
      
          foreach (string dll in Directory.GetFiles(binPath, "*.dll", SearchOption.AllDirectories))
          {
          try
          {                    
              Assembly loadedAssembly = Assembly.LoadFile(dll);
          }
          catch (FileLoadException loadEx)
          { } // The Assembly has already been loaded.
          catch (BadImageFormatException imgEx)
          { } // If a BadImageFormatException exception is thrown, the file is not an assembly.
      
          } // foreach dll
      }
      

      【讨论】:

      • “bin”目录不一定存在于已部署的 .NET 应用程序中。您应该注意,您的解决方案仅适用于 ASP.NET。
      • “bin”目录的位置位于 AppDomain.SetupInfomation 对象中。这样的用法: var assemblyDir = setup.PrivateBinPathProbe != null ? setup.PrivateBinPath : setup.ApplicationBase;
      • 在使用 Assembly.LoadFile 时要小心,因为它可能会导致加载同一程序集的多个版本(请参阅 docs 以供参考)。其实我自己碰到了这个问题。 Assembly.Load 方法更安全,可以这样使用:Assembly.Load(Path.GetFileNameWithoutExtension(dll)).
      【解决方案4】:

      我知道这是一个老问题,但是......

      System.AppDomain.CurrentDomain.GetAssemblies()

      【讨论】:

      • 我相信这只会返回调用程序集引用的程序集(当前程序集依赖的所有程序集)。这不一定等同于执行目录中存在的所有程序集。 msdn.microsoft.com/en-us/library/…
      猜你喜欢
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-05-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多