PATH environment variable and Relative File Paths - c#

Prologue - If i append PATH environment variable in windows with Installation Directory path of my application, i don't need to CD to installation directory to execute it.
Question - Would relative file path(s) in my application interpreted according to current execution path in console or according to installation directory. Strangely, in my application, the paths are being interpreted relative to current execution path, thus causing exceptions (File not found, etc).
Please help me out.

Relative paths will be interpreted relative to Environment.CurrentDirectory.
It will default to the directory where the process started in, but can be changed.

The behaviour you are encountering (relative pathes being evaluate in the context of the current working directory) is by design.
If you want to always place a file next to the currently executing assembly, this piece of code might come in handy:
public static string GetPathRelativeToExecutingAssemblyLocation(string aRelativePath)
{
return Path.Combine(
Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location),
aRelativePath);
}

Related

What is the difference between these ways of getting current directory?

They all give the same result, the location of folder that contains the exe that is being executed. I am sure there are no good or bad methods in the .net BCL. They are all appropriate in particular circumstances. Which one is appropriate for which scenario?
var appBaseDir = AppDomain.CurrentDomain.BaseDirectory;
var currentDir = Environment.CurrentDirectory;
var dir = Directory.GetCurrentDirectory();
var path = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
They all give the same result
They certainly don’t. currentDir and dir both give you the current working directory – i.e. by default the directory your executable was run from (but it can be changed during the execution).
By contrast, appBaseDir and path get the directory which contains the executing assembly’s file.
To illustrate how they differ, consider that you have an executable which sits in C:\bar\baz.exe. Now I can execute the application by entering the following chain of commands in a terminal:
$ md C:\foo
$ cd C:\foo
$ ..\bar\baz.exe
Now the current working directory is C:\foo but the application’s base directory is C:\bar. There exist analogous means of setting the working directory for other methods of launching an application (e.g. via a shortcut icon or programmatically, such as via Process.Start).
Still, the framework provides different ways of accessing this information:
Environment.CurrentDirectory quite directly conveys the meaning that the execution environment (an environment variable) is queried. Directory.GetCurrentDirectory() may actually do the same internally (I have no idea) but it encapsulates this, and rather focuses on providing the user with a logical API for querying information about directories.
AppDomain.CurrentDomain has information about the current AppDomain (roughly, the executable). Part of that information is, logically, the AppDomain’s path. By contrast, System.Reflection.Assembly gives you general information about assembles – these represent any kind of binary objects in .NET, including DLLs and EXEs. GetExecutingAssembly in particular returns the currently executed assembly. And you can get its path again by querying its Location property, which gives the physical path of an assembly file.
Consider the example above
The myTest.exe file contains the entry point and is at located at D:\myTest.exe. This exe calls via reflection a method in an assembly in F:\. This assembly contains all the find directory code.
In the command prompt I have my current directory set to C:\
Here are the results
AppDomain.CurrentDomain.BaseDirectory
D:\
Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location)
F:\
Environment.CurrentDirectory and Directory.GetCurrentDirectory()
C:\
AppDomain.CurrentDomain.BaseDirectory will give you the directory the application is running in.
Environment.CurrentDirectory & Directory.GetCurrentDirectory can change during the execution of an application. You can see the behavior if you get the value at the start of execution, then use something like OpenFileDialog, then then get the value again. You will notice that the value will have changed to where the OpenFileDialog was pointing.
I found with .net 5 that if the application is published as a self-contained single-file EXE, all of these well-known methods to get the EXE location return an empty string:
System.Reflection.Assembly.GetExecutingAssembly().Location
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase
typeof(Program).Assembly.ManifestModule.FullyQualifiedName
However this does work to get the containing folder path:
AppDomain.CurrentDomain.BaseDirectory

Get full path to file while debugging using IIS Express

I have a .NET application that I am trying to debug and part of my application loads a file from my project. This file is located at
C:\Users\USER_FOLDER\Documents\Visual Studio 2012\Projects\MY_PROJECT\_templates\myFile.html
In my code, I specify a relative path to the file and use the DirectoryInfo class to get the full directory path to my file:
string myFile = (new DirectoryInfo("_templates/myFile.html")).FullName;
However, this returns the following path (extra \'s as escape characters):
"C:\\Program Files\\IIS Express\\_templates\\myFile.html"
I was expecting the path that is returned when debugging in IIS Express would match the first path I listed, not the third. Why is this? Is there something else that I need to set up in my project to have it derive the paths properly? I'm assuming that this would not happen if I deployed my code to a IIS7 site, but I haven't gotten to that testing level yet.
Use Server.MapPath:
Server.MapPath("~/_templates/myFile.html")
or HttpServerUtility.MapPath:
HttpServerUtility.MapPath("~/_templates/myFile.html")

Getting directory based the location of file C#

I'm trying to write a relative path from a file but the only relative paths I can get are from the running app file.
This is causing problems as NCrunch runs its test from a different directory so its failing all my tests because it cant find the files which are relative to my code file.
It's important that this be a relative path as there are several people working on this project so absolute paths don't work.
Is there any way to make the path relative to the .cs file where the code is written?
until now I've been using
private static readonly string MyDocumentsRoot = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
public static readonly string ApplicationRoot = MyDocumentsRoot + #"\Visual Studio 2012\Projects\";
but really need it to be a little more relative
The solution is well documented in NCRUNCH documentation:
Implicit File Dependencies
The other solutions, sooner or later, will fail. (I had similar trouble with MSTest, which offers a similar solution).
You can try with this code - based on GetExecutingAssembly method
string path = System.Reflection.Assembly.GetExecutingAssembly().Location;
string directory= Path.GetDirectoryName( path );
Or
string path = System.Reflection.Assembly.GetAssembly(YourClass).Location;
The documentation shows the paths are relative to the project file:
For example, you could specify the following files to include:
SpecialConfiguration\ImportantConfigFile.config
..\CustomBuild\**.*
..\..\TestResources\Spreadsheets\*.xls
This would include an individual file (ImportantConfigFile.config), the entire contents of the ..\CustomBuild directory, all of its subdirectories, and all .xls files within the ..\..\TestResources\Spreadsheets directory.
All file paths must be specified relative to the project file's path on disk. When NCrunch builds a workspace, it will automatically arrange all dependent files so they exist with the same relative paths in their workspace as they did in their original location.
You can use str=Directory.getdirectory which will give you the path of the app (the folders up until Release or Debug (where your app is located) and save it in a string (the method returns a string). After doing that you can use the str.replace(str1,str2) method which locates str1 and replaces it with str2. Just don't forget that \ inside a string is \\ because \ is an escape character. If you need help with escape characters let me know so I can help you with that as well.
I usually place an old style ini-file where my executable resides. Here I store the absolute paths of files and folders required by the application. This also enables me to configure these pathes differently in a production enivronment (on the cutomers site) than on my development environment. Having just a copy of this ini-file in the folder from where NCrunch runs the assemlies would solve the problem.
My ini-file implementation searches all the folders, starting at the folder where the executable resides, towards the root folder, until it finds the ini-file. This enables me to have different executables using a common ini-file. E.g. if a place the ini-file in the bin folder both, the Debug and the Release version will automatically access the same ini-file.

File path for project files?

I am working on a media player in C# but when I want to make my test I have a problem.
I have to create a new object song with the following path:
#"C:\Users\Jesus Antonio\Desktop\JukeboxV2.0\JukeboxV2.0\Datos\ich will.mp3"
It works but when I change the computer I have to rewrite the entire path,
My project is called JukeboxV2.0
In java I remember you can just write the path for example
#"JukeboxV2.0\JukeboxV2.0\Datos\ich will.mp3"
This will save a lot of time because I can take my project to different computers and it works, but here I don't known how to do that, anyone know?
You would do something like this to get the path "Data\ich_will.mp3" inside your application environments folder.
string fileName = "ich_will.mp3";
string path = Path.Combine(Environment.CurrentDirectory, #"Data\", fileName);
In my case it would return the following:
C:\MyProjects\Music\MusicApp\bin\Debug\Data\ich_will.mp3
I use Path.Combine and Environment.CurrentDirectory in my example. These are very useful and allows you to build a path based on the current location of your application. Path.Combine combines two or more strings to create a location, and Environment.CurrentDirectory provides you with the working directory of your application.
The working directory is not necessarily the same path as where your executable is located, but in most cases it should be, unless specified otherwise.
Path.Combine(AppDomain.CurrentDomain.BaseDirectory, #"JukeboxV2.0\JukeboxV2.0\Datos\ich will.mp3")
base directory + your filename
I was facing a similar issue, I had a file on my project, and wanted to test a class which had to deal with loading files from the FS and process them some way. What I did was:
added the file test.txt to my test project
on the solution explorer hit alt-enter (file properties)
there I set BuildAction to Content and Copy to Output Directory to Copy if newer, I guess Copy always would have done it as well
then on my tests I just had to Path.Combine(Environment.CurrentDirectory, "test.txt") and that's it. Whenever the project is compiled it will copy the file (and all it's parent path, in case it was in, say, a folder) to the bin\Debug (or whatever configuration you are using) folder.
Hopes this helps someone

Environment PATH variable affecting Relative File Path(s)

I had this console application. Now i have added Environment variable PATH to its setup so that it can be executed from any location through Console. Strangely, the same application is breaking after this change.
Installation directory contains, BIN and CONFIG folder. Exe is placed inside BIN folder.
I have this line of code,
WriteToFile(#"..\Config\Settings.xml")
The path used to write to a file Settings.xml inside Config folder inside the INSTALLATION DIRECTORY. However, now it tries to write to settings.xml inside Config folder at EXECUTION PATH.
So, if i execute my app from console as c:/users/guest/app.exe, it would try to interpret path relative to this location AND NOT relative to installation directory for the application.
Any help, suggestions?
Get the path of the executing assembly then add to it the folder and file name:
string pathOfExecutingAssembly = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
string settingsPath = pathOfExecutingAssembly + "\\..\\Config\\Settings.xml"
Why don't you try getting the Executing Application's Path and append it before the path where you want to save
Path starting from \ means: start from the root directory on the current drive. \Config\Settings.xml executed from any C subdirectory gives: C:\Config\Settings.xml.
BTW, do you post exact code? It should be WriteToFile(#"\Config\Settings.xml") or WriteToFile("\Config\Settings.xml")
In any case, you need to decide, whether you want to search configuration file using absolute path, or path relative to current directory/installation directory/executable directory. The code, installation package and execution command should be changed accordingly.

Categories

Resources