112

I have a config file that I need to load as part of the execution of a dll I am writing.

The problem I am having is that the place I put the dll and config file is not the "current location" when the app is running.

For example, I put the dll and xml file here:

D:\Program Files\Microsoft Team Foundation Server 2010\Application Tier\Web Services\bin\Plugins

But if I try to reference the xml file (in my dll) like this:

XDocument doc = XDocument.Load(@".\AggregatorItems.xml")

then .\AggregatorItems.xml translates to:

C:\windows\system32\inetsrv\AggregatorItems.xml

So, I need to find a way (I hope) of knowing where the dll that is currently executing is located. Basically I am looking for this:

XDocument doc = XDocument.Load(CoolDLLClass.CurrentDirectory+@"\AggregatorItems.xml")
Vaccano
  • 78,325
  • 149
  • 468
  • 850

6 Answers6

178

You are looking for System.Reflection.Assembly.GetExecutingAssembly()

string assemblyFolder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string xmlFileName = Path.Combine(assemblyFolder,"AggregatorItems.xml");

Note:

The .Location property returns the location of the currently running DLL file.

Under some conditions the DLL is shadow copied before execution, and the .Location property will return the path of the copy. If you want the path of the original DLL, use the Assembly.GetExecutingAssembly().CodeBase property instead.

.CodeBase contains a prefix (file:\), which you may need to remove.

SSS
  • 4,807
  • 1
  • 23
  • 44
BrokenGlass
  • 158,293
  • 28
  • 286
  • 335
  • 9
    Alas! That returns `C:\\Windows\\Microsoft.NET\\Framework64\\v4.0.30319\\Temporary ASP.NET Files\\tfs\\de3c0c8e\\c1bdf790\\assembly\\dl3\\20b156cb\\22331f24_bfb9cb01\\AggregatorItems.xml` – Vaccano Jan 21 '11 at 23:02
  • 26
    Ah! But `Assembly.GetExecutingAssembly().CodeBase` has it! – Vaccano Jan 21 '11 at 23:05
  • How did you load that DLL then? I tested both with an executable and a library DLL used by another EXE and the `Location` property worked for both. – BrokenGlass Jan 21 '11 at 23:11
  • I am doing a TFS Server Side Plugin (details here: http://geekswithblogs.net/jakob/archive/2010/10/27/devleoping-and-debugging-server-side-event-handlers-in-tfs-2010.aspx) So when I put the dll in a specific folder TFS "Does its thing" and loads it up. It is possible it copies it first. Either way, `CodeBase` works great. Thanks for the help! – Vaccano Jan 21 '11 at 23:14
  • 2
    CodeBase gave me file:\\c:\myassemblypath, which is weird – Matt Jul 06 '15 at 21:24
  • 14
    @Matt use new Uri(Assembly.GetExecutingAssembly().CodeBase).LocalPath to get a real name – Larry Dec 01 '15 at 11:32
  • 6
    `string curAssemblyFolder = new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath;` – Martin Connell Apr 29 '18 at 10:37
45

Reflection is your friend, as has been pointed out. But you need to use the correct method;

Assembly.GetEntryAssembly()     //gives you the entrypoint assembly for the process.
Assembly.GetCallingAssembly()   // gives you the assembly from which the current method was called.
Assembly.GetExecutingAssembly() // gives you the assembly in which the currently executing code is defined
Assembly.GetAssembly( Type t )  // gives you the assembly in which the specified type is defined.
Nicholas Carey
  • 71,308
  • 16
  • 93
  • 135
18

In my case (dealing with my assemblies loaded [as file] into Outlook):

typeof(OneOfMyTypes).Assembly.CodeBase

Note the use of CodeBase (not Location) on the Assembly. Others have pointed out alternative methods of locating the assembly.

6
System.Reflection.Assembly.GetExecutingAssembly().Location
bluish
  • 26,356
  • 27
  • 122
  • 180
Hawxby
  • 2,746
  • 21
  • 29
  • Note: for Asp.Net apps the DLL is shadow copied before execution, and the .Location property will return the path of the copy. – mBardos Jul 24 '23 at 13:22
2

If you're working with an asp.net application and you want to locate assemblies when using the debugger, they are usually put into some temp directory. I wrote the this method to help with that scenario.

private string[] GetAssembly(string[] assemblyNames)
{
    string [] locations = new string[assemblyNames.Length];


    for (int loop = 0; loop <= assemblyNames.Length - 1; loop++)       
    {
         locations[loop] = AppDomain.CurrentDomain.GetAssemblies().Where(a => !a.IsDynamic && a.ManifestModule.Name == assemblyNames[loop]).Select(a => a.Location).FirstOrDefault();
    }
    return locations;
}

For more details see this blog post http://nodogmablog.bryanhogan.net/2015/05/finding-the-location-of-a-running-assembly-in-net/

If you can't change the source code, or redeploy, but you can examine the running processes on the computer use Process Explorer. I written a detailed description here.

It will list all executing dlls on the system, you may need to determine the process id of your running application, but that is usually not too difficult.

I've written a full description of how do this for a dll inside IIS - http://nodogmablog.bryanhogan.net/2016/09/locating-and-checking-an-executing-dll-on-a-running-web-server/

Bryan
  • 5,065
  • 10
  • 51
  • 68
1

Try this

System.IO.Path.GetDirectoryName(new System.Uri(System.Reflection.Assembly.GetExecutingAssembly().CodeBase).LocalPath)