Click here to Skip to main content
Click here to Skip to main content

Get an Executable Assembly Name

, 17 Oct 2008
Rate this:
Please Sign up or sign in to vote.
Use GetEntryAssembly to obtain an executable's assembly name - even from a DLL.

Introduction

This little example shows how you can obtain the assembly name of an executable, even if you seek it from a DLL called by that executable.

Background

I was looking for a reliable way to get the assembly name of the original starting executable. I found plenty of examples of using System.Environment.GetCommandLineArgs()[0], but it returns the path to the executable file name, not the assembly name defined in the Project Properties.

Additionally, I did not want the full path, just the name of the assembly, even if the file name had changed. Sure, I could use System.IO.Path.GetFileNameWithoutExtension(path) to get the name, but that would not allow me to express my true OCD Personality Type nature Smile | :) . If called within the IDE, you would get "ExeName.vshost".

Finally, I wanted to obtain the name of the original executable assembly, even if from a DLL called by the executable. How did I finally satisfy my own personal obsessive nature and find a hackless solution?

Using the code

The GetEntryAssembly() method returns the assembly of the first executable that was executed. I used the following to obtain the assembly name of the original executable:

C#:

string name = System.Reflection.Assembly.GetEntryAssembly().GetName().Name;

Visual Basic .NET

Dim name as String = System.Reflection.Assembly.GetEntryAssembly().GetName().Name; 

We could use System.Windows.Forms.Application.ProductName in Visual Basic, but it does not return the assembly name - it returns the assembly Product Name (a slight distinction - again that whole OCD thing Smile | :)

If you use this code in a DLL file, it will still return the assembly name of the executable that called on the DLL. I use this method in a generic logging class that I call from many different projects - I would like the entries it makes to contain the assembly name of the program that used the DLL. It even returns the original assembly name when the DLL is called from another DLL that was called by the original EXE! (Whew! Time for medication. Smile | :)

The sample application produces these message boxes:

AppExample.PNG

from this executable's assembly:

AssemblyName.png

Enjoy!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

hayes.adrian
Systems Engineer ThomsonReuters Tax & Accounting
United States United States
I am a Senior System Administrator for a 400+ server ASP farm. With such a large farm and limited staff, our goal is to add as much automation as possible to the system. Most of my programming consists of intelligent slack: spending 2 hours to write a program that handles a reoccurring 10 minute manual job.

Comments and Discussions

 
GeneralThanks! PinmemberSergey A Alekseev11-Aug-13 6:42 
GeneralMy vote of 1 PinmemberKarstenK31-Oct-10 23:53 
GeneralThanks! PinmemberWes Jones18-May-09 13:24 
GeneralHere some code you may find useful [modified] PinmemberIlíon20-Oct-08 4:19 
This code returns various custom attributes of the assembly, either of the calling assembly or of the executing assembly:
private static bool Assembly_GetCustomAttributes(
    bool fromRootAssembly, int traceFrame, 
    ref string assemblyPath, bool getPathWithoutFileName,
    ref string assemblyFileName, bool getFileNameWithoutExtension,
    ref string assemblyCompany,
    ref string assemblyDescription,
    ref string assemblyName,
    ref string assemblyProduct,
    ref string assemblyTitle,
    ref string assemblyVersion
)
{
    System.Reflection.Assembly asm;
    if (fromRootAssembly)
    {
        asm = GetRootAssembly();
    }
    else
    {
        asm = GetParentAssembly(traceFrame + 1);
    }
 
    if (asm != null)
    {
        foreach (System.Attribute attr in System.Attribute.GetCustomAttributes(asm))
        {
            if (attr.GetType() == typeof(System.Reflection.AssemblyCompanyAttribute))
            {
                assemblyCompany = ((System.Reflection.AssemblyCompanyAttribute)attr).Company.Trim();
            }
            else
            if (attr.GetType() == typeof(System.Reflection.AssemblyDescriptionAttribute))
            {
                assemblyDescription = ((System.Reflection.AssemblyDescriptionAttribute)attr).Description.Trim();
            }
            else
            if (attr.GetType() == typeof(System.Reflection.AssemblyProductAttribute))
            {
                assemblyProduct = ((System.Reflection.AssemblyProductAttribute)attr).Product.Trim();
            }
            else
            if (attr.GetType() == typeof(System.Reflection.AssemblyTitleAttribute))
            {
                assemblyTitle = ((System.Reflection.AssemblyTitleAttribute)attr).Title.Trim();
            }
            else
            if (attr.GetType() == typeof(System.Reflection.AssemblyVersionAttribute))
            {
                assemblyVersion = ((System.Reflection.AssemblyVersionAttribute)attr).Version.Trim();
            }
        }
 
        if (assemblyVersion.Length <= 0)
        {
            assemblyVersion = asm.GetName().Version.ToString();
        }
        assemblyName = asm.GetName().Name.Trim();
 
        //string asmLocation = asm.Location.ToString();                // (returns path in lowercase)
        //asmLocation = Pathing.GetProperCase(asmLocation);            // Fix case of returned path
        string asmLocation = Pathing.GetProperCase(asm.Location.ToString());
        if (getPathWithoutFileName)
        {
            assemblyPath = Pathing.GetDirectoryName(asmLocation);
        }
        else
        {
            assemblyPath = asmLocation;
        }
        if (getFileNameWithoutExtension)
        {
            assemblyFileName = Pathing.GetFileNameWithoutExtension(asmLocation);
        }
        else
        {
            assemblyFileName = Pathing.GetFileName(asmLocation);
        }
        return true;
    }
    return false;
}
 
public static System.Reflection.Assembly GetParentAssembly(int traceFrame)
{
    System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace();
    System.Diagnostics.StackFrame parentFrame = trace.GetFrame(traceFrame + 1);
    //System.Reflection.MethodBase parentMethod = parentFrame.GetMethod();
    //System.Type parentType = parentMethod.DeclaringType;
    //return parentType.Assembly;
    return parentFrame.GetMethod().DeclaringType.Assembly;
}
 
public static System.Reflection.Assembly GetRootAssembly()
{
    System.Diagnostics.StackTrace trace = new System.Diagnostics.StackTrace();
    System.Diagnostics.StackFrame parentFrame = trace.GetFrame(trace.FrameCount - 1);
    //System.Reflection.MethodBase parentMethod = parentFrame.GetMethod();
    //System.Type parentType = parentMethod.DeclaringType;
    //return parentType.Assembly;
    return parentFrame.GetMethod().DeclaringType.Assembly;
}
 
OOPS! I guess one would need to see the methods of the [Pathing] class:
internal class Pathing
{
    public static string GetProperCase(string parmFullPathFileName)
    {
        // From a presumed full Path+FileName, return the Path in proper case
        // (This method doesn't work for NetWork paths [i.e. "\\Server\RootPath\path"])
        string returnPath = parmFullPathFileName.Trim();
        #region Is there any point in executing this method?
        string driveLetter = " ";
        if (returnPath.Length > 0)
        {
            driveLetter = returnPath.Substring(0, 1).ToUpper();
        }
        if( (returnPath.Length < 4)                            // Minimum size/format: "Z:\x"
        || (driveLetter.CompareTo("A") < 0) || (driveLetter.CompareTo("Z") > 0)
        || (returnPath.Substring(1, 1) != @":")
        || (returnPath.Substring(2, 1) != @"\")
        )
        {
            return returnPath;
        }
        #endregion 
 
        string casedPath = "";
        string[] nodes = StringArrayFrom.NodeElements(@"\", returnPath);
        if (nodes.Length > 0)
        {
            #region Initialize local variables
            string rootNode = "";
            int idxSkip = 0;
            if (nodes[0].Length > 0)
            {
                rootNode = nodes[0].ToUpper() +@"\";
                idxSkip = 1;
            }
            //else
            //{
            //    // NetWork path [i.e. "\\Server\RootPath\path"])
            //    rootNode = @"\\"+ nodes[2] +@"\" + nodes[3];
            //    idxSkip = 4;
            //}
            #endregion 
 
            #region Loop through the nodes [parmFullPathFileName] and build [casedPath]
            System.IO.DirectoryInfo rootDirInfo = new System.IO.DirectoryInfo(rootNode);
            for (int idx = idxSkip; idx < nodes.Length; idx++)
            {
                string node = nodes[idx];
                if (node.Length > 0)
                {
                    System.IO.FileSystemInfo[] fsInfos = rootDirInfo.GetFileSystemInfos(node);
                    if (fsInfos.Length == 1)
                    {
                        casedPath = fsInfos[0].FullName;
 
                        rootDirInfo = new System.IO.DirectoryInfo(casedPath);
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }
               #endregion 
        }
 
        if (casedPath.ToLower() == returnPath.ToLower() )
        {
            returnPath = casedPath;
        }
        return returnPath;
    }
 
    public static string GetDirectoryName(string parmFullPathFileName)
    {
        // From a presumed full Path+FileName, return the Path (Directory Name)
        string returnPath = parmFullPathFileName.Trim();
        if (returnPath.Length > 0)
        {
            try
            {
                returnPath = System.IO.Path.GetFullPath(returnPath);    // (just in case) Get absolute path
                returnPath = System.IO.Path.GetDirectoryName(returnPath);
                if (returnPath != null)
                {
                    return returnPath;
                }
            }
            catch
            {}
        }
        return "";                                      // indicate failure
    }
 
    public static string GetFileName(string parmFullPathFileName)
    {
        // From a presumed full Path+FileName (but FileName only should be OK), return the FileName
        return GetFileName_Work(parmFullPathFileName, false, false);
    }
  
    public static string GetFileNameWithoutExtension(string parmFullPathFileName)
    {
        // From a presumed full Path+FileName (but FileName only should be OK), return the FileName without extension
        return GetFileName_Work(parmFullPathFileName, true, false);
    }
}

 
modified on Monday, October 20, 2008 12:08 PM

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 17 Oct 2008
Article Copyright 2008 by hayes.adrian
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid