Better way to get the base directory?
Asked Answered
F

9

20

I have this code to load a config file and read all the values and it works fine when running the application but of course fails on team city because the appdomain's base directory is where the build script (psake) is started. I know I can change directory to the build dir before executing the tests but I thought it's better to make loading the config file work at all times regardless.

XDocument.Load(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, cfgFile));

Is there another way to get the "BaseDirectory" that really works all times? I tried the below as well with same results:

string path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase);
XDocument.Load(Path.Combine(path, cfgFile));

EDIT 1 The problem is the following. My solutions base directory is "C:\Project", all compiled files are copied to "C:\Project\build". Now in the psake build script I have the following code:

task Test -depends PrepareTests {
    try { 
        #$old = pwd
        #cd $build_dir
        &$mspec $mspec_projects --teamcity
        #cd $old
    }
    catch {
        &echo "Error starting test runner"
        Exit 1;
    }      
}

As you can see I commented out the changing of directories which makes the BaseDirectory the location of the build file / solution instead of the build directory regardless of how I try to access it. Kind of confusing if you ask me.

UPDATE I really like to know if it is possible to get the directory of the assembly regardless of what directory the application that started the app domain is located. How?

Fury answered 2/7, 2010 at 5:47 Comment(4)
What do you mean "base directory"? Where is the config file located in relation to the assembly? Your second example should work if the config file is in the same directory as the DLL...Skewbald
So you want the directory where the .exe is located?Inanna
@craig - yes that's what I am afterFury
Have simply tried asking for the CodeBase off one of the types in your assembly? I.e. something like var path = typeof(SomeClassInMyAssembly).Assembly.CodeBase;?Kestrel
U
11
string origAssemblyLocation = Assembly.GetExecutingAssembly().CodeBase;

Per MSDN:

Assembly.CodeBase Property

Gets the location of the assembly as specified originally

Uganda answered 24/7, 2010 at 7:12 Comment(2)
I had to remove the name of the dll but it does indeed get me the location on disk of the assembly!Fury
beware, this gives a uri-type string, i.e. file:///foo/bar/baz.DLLVosges
A
29

differents ways to get the base directory

  1. AppDomain.CurrentDomain.BaseDirectory

  2. Directory.GetCurrentDirectory() // not guaranteed to work on Mobile application

  3. Environment.CurrentDirectory // this calls Directory.GetCurrentDirectory()

  4. this.GetType().Assembly.Location // Assembly.location

  5. Application.StartupPath // for windows forms apps

  6. Application.ExecutablePath // same as Application.StartupPath

Amorette answered 20/4, 2012 at 12:24 Comment(0)
M
13

Your question is a bit unclear. I don't really know if this is what you want.

I typically use AppDomain.CurrentDomain.BaseDirectory

Alternatives

  • Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)
  • Environment.CurrentDirectory
Mastigophoran answered 2/7, 2010 at 5:59 Comment(1)
Thank you for the suggestion but it produces the same result.Fury
U
11
string origAssemblyLocation = Assembly.GetExecutingAssembly().CodeBase;

Per MSDN:

Assembly.CodeBase Property

Gets the location of the assembly as specified originally

Uganda answered 24/7, 2010 at 7:12 Comment(2)
I had to remove the name of the dll but it does indeed get me the location on disk of the assembly!Fury
beware, this gives a uri-type string, i.e. file:///foo/bar/baz.DLLVosges
S
9

So it sounds/looks like you're attempting to obtain the configuration file for an assembly. The following should accomplish that task by accessing the 'Location' property of the assembly and using it to retrieve the configuration path:

static string GetConfigFileByType(Type type)
{
    Configuration config = 
        ConfigurationManager.OpenExeConfiguration(type.Assembly.Location);

    if (config.HasFile)
        return config.FilePath;
    throw new FileNotFoundException();
}
Sleet answered 19/7, 2010 at 17:29 Comment(0)
K
1

try this one:

  Module[] modules = Assembly.GetExecutingAssembly().GetModules();
  return Path.GetDirectoryName(modules[0].FullyQualifiedName);
Kassandrakassaraba answered 2/7, 2010 at 6:58 Comment(2)
Thank you I did not try that one before. It still tries to find the xml file in the solution dir instead of the build dir though.Fury
you may registrate the assembly file in build directiry after copy them.Kassandrakassaraba
A
1

have you tried getting the FileName of the current process' MainModule?

System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName

Or GetEntryAssembly()?

System.Reflection.Assembly.GetEntryAssembly().Location
Apache answered 18/7, 2010 at 10:43 Comment(0)
P
1

I like to make my classes configurable - for example they get the folder name as a parameter in their constructor. This makes it possible to test with different config files.

In test code we use:

TestContext.TestDeploymentDir

This is the testrun folder, where all assemblies for a test run are copied into, together with the test deployment items. We 'deploy' our unit test config files to the test run folder - this can be specified in the testrunconfig dialog in visual studio.

For our production code we pass

Assembly.GetExecutingAssembly().Location

to the constructor, which works for us.

Promotive answered 21/7, 2010 at 11:16 Comment(2)
"If the loaded file was shadow-copied, the location is that of the file after being shadow-copied." / The Location property won't give the OP what he's after in this case.Uganda
As a side note, this is best if you plan on using the desktop bridgeInsalivate
E
1

how about:

Application.StartupPath;
Evoy answered 23/7, 2010 at 13:22 Comment(0)
T
0
string baseDirectory=Application.StartupPath.Split(Path.DirectorySeparatorChar)[0];

Application startup path will return the path where exe is kept, we will split this using "\" and get the base directory as "C:" for example,

Tungstite answered 15/5, 2018 at 8:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.