42

In a web application, I want to load all assemblies in the /bin directory.

Since this can be installed anywhere in the file system, I can't gaurantee a specific path where it is stored.

I want a List<> of Assembly assembly objects.

mrblah
  • 99,669
  • 140
  • 310
  • 420

4 Answers4

60

Well, you can hack this together yourself with the following methods, initially use something like:

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

to get the path to your current assembly. Next, iterate over all DLL's in the path using the Directory.GetFiles method with a suitable filter. Your final code should look like:

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

Please note that I haven't tested this so you may need to check that dll actually contains the full path (and concatenate path if it doesn't)

Jon Egerton
  • 40,401
  • 11
  • 97
  • 129
Wolfwyrd
  • 15,716
  • 5
  • 47
  • 67
  • 2
    You'll probably also want to add a check to ensure you don't add the Assembly that you're actually running as well :) – Wolfwyrd Aug 17 '09 at 15:10
  • 8
    The `path` variable contains the directory filename, it needs to be shortened with `Path.GetDirectoryName(path)` – cjk Jul 29 '10 at 11:28
  • For my ASP.NET application it seems like CodeBase contains the correct path. Use Uri.LocalPath to remove the file://-part. – Thomas Eyde Jan 28 '14 at 12:17
  • Don't forget to check for "*.exe" too, since executable files can also be assemblies. By the way, there is a better method to enumerate files in .NET 4+. Take a look to this question http://stackoverflow.com/questions/163162/can-you-call-directory-getfiles-with-multiple-filters – SuperJMN Aug 21 '15 at 14:47
53

To get the bin directory, string path = Assembly.GetExecutingAssembly().Location; does NOT always work (especially when the executing assembly has been placed in an ASP.NET temporary directory).

Instead, you should use string binPath = System.IO.Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "bin");

Further, you should probably take the FileLoadException and BadImageFormatException into consideration.

Here is my working function:

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
}
Julien Poulin
  • 12,737
  • 10
  • 51
  • 76
Jason S
  • 1,129
  • 11
  • 10
  • 8
    The "bin" directory won't necessarily exist in a deployed .NET Application. You should note that your solution only works for ASP.NET. – BSick7 Jun 07 '11 at 13:56
  • The location of the "bin" directory is located in the AppDomain.SetupInfomation object. Usage as such: var assembliesDir = setup.PrivateBinPathProbe != null ? setup.PrivateBinPath : setup.ApplicationBase; – Paul Easter Oct 06 '15 at 09:27
  • Be carefull about using the Assembly.LoadFile, because it can cause multiple versions of the same assembly to be loaded (see the [docs](https://learn.microsoft.com/en-us/dotnet/framework/deployment/best-practices-for-assembly-loading#avoid-loading-multiple-versions-of-an-assembly-into-the-same-context) for reference). Actually I bumped into this problem by myself. The Assembly.Load method is more safe, you can use it like this: Assembly.Load(Path.GetFileNameWithoutExtension(dll)). – victorm1710 Jun 21 '19 at 15:49
6

You can do it like this, but you should probably not load everything into the current appdomain like this, since assemblies might contain harmful code.

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

EDIT: I have not tested the code (no access to Visual Studio at this computer), but I hope that you get the idea.

Patrik Svensson
  • 13,536
  • 8
  • 56
  • 77
-3

I know this is a old question but...

System.AppDomain.CurrentDomain.GetAssemblies()

xspydr
  • 3,030
  • 3
  • 31
  • 49
  • 12
    I believe this only returns the assemblies that are referenced by the calling assembly (all assemblies the current assembly depends on). This does not necessarily equate to all assemblies present in the executing directory. http://msdn.microsoft.com/en-us/library/system.appdomain.getassemblies.aspx – Jason Nov 23 '12 at 23:37