views:

87

answers:

4

A simple question. I have an ASP.NET web application which contains several assemblies and I need to create a list of version information for every assembly in the web site. (And perhaps even a few others too, but the focus is mostly for the site itself.)

This list will be displayed within the same application on a protected page and is used to validate the installation and upgrades for the website. Of course, I could just walk through all binaries in the BIN folder and extract information from them but is there a better option to do this?

And second question: what's the best method to just extract version information from another assembly? But I guess that one has asked before and I can find an answer to this myself. (Something with reflection, GetExecutingAssembly and some more stuff.)

+6  A: 
IEnumerable<String> GetLoadedAssemblies() {
    foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) {
        yield return assembly.ToString();
    }
}

Gives you the name (including version number) of every assembly being used in the app domain.

mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

etc.

One possible gotcha with using this: if the website has just started then some of the assemblies you are interested in might not have been loaded into the AppDomain yet, as they're unlikely to be referenced by a special page with just this functionality on it. If you click around the site first to make sure everything is loaded it should work OK, but if you need something more robust you'd have to add some AppDomain.Load() statements to the above code.

Matt Howells
Works great and finds more than the stuff I could come up with. :-) Thanks!
Workshop Alex
+1  A: 

You could also use the GetReferencedAssemblies() method of the Assembly class to get all of the assemblies referenced by your web application.

adrianbanks
+1  A: 

In reference to your second part, I think you would have difficulties in getting the information from an assembly without loading it. If you don't plan to actually use the assembly, it's probably not something you want to carry around with you, as you can't unload an assembly from your AppDomain.

Look at creating a new AppDomain and loading the assembly in that to get the info you want. Then you can throw away the new appdomain, and lose all the assembly references when you're done.

Here's a blog post on Using AppDomain to Load and Unload Dynamic Assemblies.

Edit: Even better: Thread on StackOverFlow

Christopher Karper
+1  A: 

I whipped up this page:

<%@ Page Language="C#" %>
<%@ Import Namespace="System.Collections.Generic" %>
<%@ Import Namespace="System.Reflection" %>
<script runat="server">
void Page_Load(Object sender, EventArgs e)
{
    List<string> assemblyNames = GetLoadedAssemblyNames(false);
    StringBuilder sb = new StringBuilder();
    foreach (string ass in assemblyNames)
    {
        sb.AppendFormat("{0}\n", ass);
    }

    this.Results.Text = sb.ToString();
}

private static List<string> GetLoadedAssemblyNames(bool hideSystem)
{
    List<string> names = new List<string>();

    foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
    {
        string name = a.GetName().FullName;
        if (hideSystem && (name.StartsWith("System.") || name.StartsWith("Microsoft.")))
        {
            continue;
        }

        names.Add(name);
    }

    names.Sort();
    return names;
}
</script>
<html>
<body>
<form id="form1" runat="server">
 <h1>Loaded Assemblies</h1>
 <p><asp:Literal runat="server" ID="AppName" /></p>
 <pre><asp:Literal runat="server" ID="Results" /></pre>
</form>
</body>
</html>
devstuff