C# Getting Parent Assembly Name of Calling Assembly

30,367

Solution 1

I guess you should be able to do it like this:

using System.Diagnostics;
using System.Linq;

...

StackFrame[] frames = new StackTrace().GetFrames();
string initialAssembly = (from f in frames 
                          select f.GetMethod().ReflectedType.AssemblyQualifiedName
                         ).Distinct().Last();

This will get you the Assembly which contains the first method which was started first started in the current thread. So if you're not in the main thread this can be different from the EntryAssembly, if I understand your situation correctly this should be the Assembly your looking for.

You can also get the actual Assembly instead of the name like this:

Assembly initialAssembly = (from f in frames 
                          select f.GetMethod().ReflectedType.Assembly
                         ).Distinct().Last();

Edit - as of Sep. 23rd, 2015

Please, notice that

GetMethod().ReflectedType

can be null, so retrieving its AssemblyQualifiedName could throw an exception. For example, that's interesting if one wants to check a vanilla c.tor dedicated only to an ORM (like linq2db, etc...) POCO class.

Solution 2

This will return the the initial Assembly that references your currentAssembly.

var currentAssembly = Assembly.GetExecutingAssembly();
var callerAssemblies = new StackTrace().GetFrames()
            .Select(x => x.GetMethod().ReflectedType.Assembly).Distinct()
            .Where(x => x.GetReferencedAssemblies().Any(y => y.FullName == currentAssembly.FullName));
var initialAssembly = callerAssemblies.Last();

Solution 3

It worked for me using this:

System.Reflection.Assembly.GetEntryAssembly().GetName()

Solution 4

Assembly.GetEntryAssembly() is null if you run tests from nunit-console too.

If you just want the name of the executing app then use:

 System.Diagnostics.Process.GetCurrentProcess().ProcessName 

or

 Environment.GetCommandLineArgs()[0];

For nunit-console you would get "nunit-console" and "C:\Program Files\NUnit 2.5.10\bin\net-2.0\nunit-console.exe" respectively.

Solution 5

Try:

Assembly.GetEntryAssembly().ManifestModule.Name

This should be the assembly that was actually executed to start your process.

Share:
30,367
Saroop Trivedi
Author by

Saroop Trivedi

Updated on April 23, 2020

Comments

  • Saroop Trivedi
    Saroop Trivedi about 4 years

    I've got a C# unit test application that I'm working on. There are three assemblies involved - the assembly of the C# app itself, a second assembly that the app uses, and a third assembly that's used by the second one.

    So the calls go like this:

    First Assembly ------> Second Assembly---------> Third Assembly.
    

    What I need to do in the third assembly is get the name of the Fist Assembly that called the second assembly.

    Assembly.GetExecutingAssembly().ManifestModule.Name
    Assembly.GetCallingAssembly().ManifestModule.Name
    

    returns the name of the Second assembly. and

    Assembly.GetEntryAssembly().ManifestModule.Name
    

    return NULL

    Does anybody know if there is a way to get to the assembly name of the First Assembly?

    As per the other users demand here I put the code. This is not 100% code but follow of code like this.

    namespace FirstAssembly{
    public static xcass A
    {
            public static Stream OpenResource(string name)
            {
                return Reader.OpenResource(Assembly.GetCallingAssembly(), ".Resources." + name);
            }
    }
    }
    
    using FirstAssembly;
    namespace SecondAssembly{
    public static class B 
    
    {
    public static Stream FileNameFromType(string Name)
    
    {
    return = A.OpenResource(string name);
    }
    }
    }
    

    and Test project method

    using SecondAssembly;
    namespace ThirdAssembly{
    public class TestC
    {
    
     [TestMethod()]
            public void StremSizTest()
            {
                // ARRANGE
                var Stream = B.FileNameFromType("ValidMetaData.xml");
                // ASSERT
                Assert.IsNotNull(Stream , "The Stream  object should not be null.");
            }
    }
    }
    
  • Me.Name
    Me.Name almost 12 years
    Ah, the manifestmodule name returns null, how about: Assembly.GetEntryAssembly().FullName (or GetName() depending on your needs)
  • Botz3000
    Botz3000 almost 12 years
    @sarooptrivedi I added another option.
  • Saroop Trivedi
    Saroop Trivedi almost 12 years
    @Botz3000:I used this calling of Assembly in unittest project.
  • Botz3000
    Botz3000 almost 12 years
    @sarooptrivedi What kind of unit test? If the assemblies are loaded by native code (not sure how your unit testing framework is set up), GetEntryAssembly() will return null. Did you try the second option already?
  • Saroop Trivedi
    Saroop Trivedi almost 12 years
    @Botz3000: I have some resources files in Test project. I don't want to deploy all files through the DeploymentItem.So I create one project inwhich I use that all files in my unit test with help of creating one test helper project B.But the Assembly calling project is in some another helper project C. So When I get the Assembly reference of Unit test project into Project C then for GetEntryAssembly() it's return NULL.
  • Saroop Trivedi
    Saroop Trivedi almost 12 years
    I know all unit test rule. Now my point is I don't want to read all assembly. Simply I want A reference in C. This thing make my code complex.
  • habakuk
    habakuk almost 12 years
    @sarooptrivedi If you use MStest you can add items, that should be deployed for all tests, to your testsettings-file.
  • leigero
    leigero about 9 years
    Posting code-only answers is frowned upon as it does nothing to help the OP understand their problem or your solution.
  • Piotr Kula
    Piotr Kula over 8 years
    This is a great answer! Really helped me get to what I needed
  • dinotom
    dinotom over 7 years
    18 months later you post an answer the same as the one above yours?
  • Dorus
    Dorus about 6 years
    Why do you need .Distinct() if you follow with .Last()?
  • Jack Miller
    Jack Miller over 5 years
    @Dorus because you could (will?) get a wrong result otherwise, e.g. I got mscorlib without .Distinct().
  • Dorus
    Dorus over 5 years
    @JackMiller That seems very strange to me, actually as if the last frame is mscorlib and your stack is something like aba where the second a is filtered out by distinct and last then takes the b.
  • Jack Miller
    Jack Miller over 5 years
    I totally agree with you. It IS very strange. On the other hand I did not try to find out how .Distinct() actually works.
  • David Burg
    David Burg almost 3 years
    Worked well with synchronous calls. With async code, the stack seen in GetFrames() doesn't match where the async execution resumed from so I don't see who actually called. VS debugger is able to tell where the async execution resumed from, so there is a way to figure out who start the async execution. Anyone knows how to tweak the solution to also work with async callers?