Get current dir in a class library - c#

I'm developing a C# library with .Net Framework 4.5.1 to use it in a Windows 8.1 desktop application.
Inside this library project I have a JSON file, and I want to load it. First, I have tried to get current directory with this:
string currentDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
But, I have test it and Assembly.GetEntryAssembly() is null.
Maybe, I can use a resource file instead of a JSON file.
This is the method:
private void LoadData()
{
string currentDir =
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
string file =
Path.Combine(currentDir, cardsDir, cardsFile);
string json =
File.ReadAllText(file);
Deck = JsonConvert.DeserializeObject<Card[]>(json);
}
Any idea? Is there a better approach? How can I get current dir?

Yeah, you have to take into account #Hagai Shahar answer, the way to go would be using AppDomain.CurrentDomain.BaseDirectory

try this
Environment.CurrentDirectory
this will return the current working directory of your application. now you can access any file relative to your application
string currentDir = Path.GetDirectoryName(Environment.CurrentDirectory);

Pay attention that Environment.CurrentDirectory does not necessarily return the directory that contains the application files. It depends on where you started the application from.
For example, if the exe file is located at C:\User\ProgramName\prog.exe but you start the application from cmd like this:
C:\> C:\User\ProgramName\prog.exe
...the result of Environment.CurrentDirectory will be C:\ and not C:\User\ProgramName.
Furthermore, it happens also in shortcuts:
See the "Start In" property? If this is set it will become the result of Environment.CurrentDirectory because the application will be started from there.
Another solution is to get the location of the assembly which runs the application, something like this:
typeof(Program).Assembly.Location

You can't refer something within your class library using paths relative to it because you library will be a .dll file, not a folder structure. What you can do is to set the file's Copy if newer property to Copy always. This way, your json will be copied to the debug folder, along with the project.
It means that your file will be placed in the Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) folder, which means that your LoadData() will work fine

Related

How to move two folder back

I have file in my application on root directory.
When I'm using below code:
string startupPat = System.IO.Directory.GetCurrentDirectory();
It's taking also ...\bin\Debug\
How to move avoid this?
working code:
string test= File.ReadAllText(Path.Combine(System.IO.Directory.GetCurrent‌​Directory(), "..\\..\\test.txt"));
\bin\Debug is the default folder your program will be compiled into. If you run your program from Visual Studio this will most likely be the current directory. Anyway, when you copy the program to another folder, the System.IO.Directory.GetCurrentDirectory() should return that folder.
For your file you have to set copy to output directory to always in the properties in order to copy the file to where your program will be.
For all files that live in the same directory as your program does you do noth need any paths, you can just use the relative file names
var textReadFromFile = File.ReadAllText("myfile.txt");

Want to place data files for WinForm app in folder and get its path in code

I want to use a data file and read it from a WinForms app. If I use methods like Application.ExecutablePath or Application.StartupPath they reference the folder ..\bin\debug, which is different in non VS hosted app. I want to use a folder off the root folder and get a reference to it regardless if I am in debug mode or not, ie, it always works right.
What's a good way to do it? I prefer not to use an embedded resource file and not use hard coded full paths. It needs to be a relative path off the app's root folder.
Something like ~/App_Data in ASP.NET
Addition:
I want to use a relative path off "some path". "Some path" is what I am seeking, regardless if I am in VS in debug mode, non debug mode or if the app is deployed. Just like ASP.NET's "~". It doesn't care where the site is or if you're in VS. I don't want to create a folder under 'debug' folder. It's the same folder no matter what. "Some folder" is also off the VS's app folder because the app will be zipped to be used without deployment or publishing.
Try accessing the location of the current executing assembly:
string path = System.Reflection.Assembly.GetExecutingAssembly().Location
string fullFilePath = Path.Combine(path, "myfile");
..do something with your data file.
This gives you the directory where your EXE/DLL assembly is been executed. Then you could create a subdirectory for your data files. This sometiomes does not work with unit tests framework.
My solution. Go up two folder levels and then to data folder:
string appPath = Path.GetDirectoryName(Application.ExecutablePath);
System.IO.DirectoryInfo directoryInfo = System.IO.Directory.GetParent(appPath);
System.IO.DirectoryInfo directoryInfo2 = System.IO.Directory.GetParent(directoryInfo.FullName);
string path = directoryInfo2.FullName + #"\data";
ExecutablePath will work right as long as your data files will be in the bin also in release and prod deployment. The point is more that usually that is not the best place to have changing files like databases in that case I think you should use SpecialFolders like ApplicationData.
You probably want to use the Environment.GetFolderPath method and pass it one of the enums for the various sytem data folders. A full call might look like
return Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
I did it this way. first i add local db in app_data folder in my winform application and then i add EF code first for existing db. then a connection string was added in my app.config file.
<connectionStrings>
<add name="EmployeeDB" connectionString="data source=(LocalDB)\v11.0;attachdbfilename=|DataDirectory|\Database1.mdf;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
</connectionStrings>
when i try to connect my local db by EF to fetch data then i got error because my db was in app_data folder. so i add DataDirectory path to app domain then problem was resolved.
here is small code.
AppDomain.CurrentDomain.SetData("DataDirectory", AppDomain.CurrentDomain.BaseDirectory + "App_Data");
EmployeeDB db = new EmployeeDB();
var data = db.Employees.ToList();
i hope my answer would help some one in future. thanks

XNA: Load from subfolder in Content

I'm running into a lot of trouble while attempting to streamline XNA texture loading. I've given up on dynamically loading textures from a specified directory, so now I'm just trying to work with an organized collection of folders in the solution's content. I'm trying to use the following line of code:
Content.Load<Texture2D>(".\\Graphics\\Characters\\Char1");
"Char1" is the correct asset name, and it is stored in "Graphics\Characters" under Content in my solution explorer, but it still throws a "file not found" error. What am I doing wrong here?
EDIT: Turns out the debug bin folder created the wrong directory stucture: \Graphics\Characters\Characters. Thanks for the help regardless!
Try removing your leading slash. eg,
Content.Load<Texture2D>("Graphics\\Characters\\Char1");
Are you using a content project for these assets? You can set the 'Content Root' directory and the assets are all in relative paths from there.
Have a look at this msdn entry, hopefully that might help you out. Good luck.
From what you're saying, that the file is located in 'Content', make sure you do this before loading up anything:
Content.RootDirectory = "Content"
And get rid of the '.\' part.
You can set the RootDirectory property in Content to the root location of your content files. This will make your paths work correctly.
Also, no need for the single dot .\
What is your working directory? Typically it is bin\Debug (the location of the exe that is generated) and unless you are telling Visual Studio to copy your content files to this directory they are not located there.
Several options to fix this
You can add your content files to Visual Studio and set them to Deploy mode of Copy
You can manually copy them once
You can check to see if the current directory contains a particular file and go up two levels if it does not
You can use a constant to define the base directory and flex it depending on whether you are debugging or not.
Here is an example of 3
private string BaseDirectory = ".";
if (!Directory.Exists(".\Graphics"))
{
BaseDirectory = #"..\..";
}
...
Content.Load<Texture2D>(BaseDirectory + #"\Graphics\Characters\Char1");
Here is an example of the 4, note that if you are running in release mode this won't work too smoothly.
#if DEBUG
private const string BaseDirectory = #"..\..";
#else
private const string BaseDirectory = #".";
#endif
...
Content.Load<Texture2D>(BaseDirectory + #"\Graphics\Characters\Char1");
Also note that a string that starts with # does not allow \ escapes and is thus much easier to use to define directories.

Hard Coded Paths in a .NET Program

I am developing an application in C#. I have a folder called myfolder it contains a file called mypoints.bmp. The folder myfolder is in my project folder it is in D drive. The path is D:\Myproject\myfolder\mypoints.bmp.
Now, in my program, whereever I need mypoints.bmp I have hardcoded the whole path. When my project is copied in to a different system under C drive, I am not able to run my project because of the hardcoded path. How can I give the path so that there will not be any problem even if it is loaded in to a different system under a different drive.
The best would be to store the path in a configuration file.
Add -> New Item -> Application Configuration File
Then you can use the following class to pull the value you're looking for:
System.Configuration.ConfigurationManager
Have a look here on the usage.
If the images you are referring to are non-changing and are simply acting as a resource for your application then you could consider embedding them in resource files which are compiled as part of your assembly. That way you need never worry about paths or copying them.
If the BMP file is used in the code and is accessed in runtime, there is no point in keeping it just in the project directory. it should be also present in the outputdirectory.
i.e you could write a post-build command to copy your folder to the output directory.
like copy "$(ProjectDir)\MyFolder\*.*" "$(OutDir)"
then in the code you could just write the relative path i.e "MyFolder\MyPoints.bmp"
But please remember one thing. If this BMP file is not going to change through out your program execution, it is better that you put it as a resource.
You can use something like GetCurrentPath(), which will return your .exe file path, then add to this path your \myfolder\mypoints.bmp. This will not be depend on C or D or ... drive and folder
There is one path that you can always reliably find, no matter how your program got deployed to the target machine: the directory in which your .exe is stored.
Take advantage of this, put the .bmp file in the same directory. Or a subdirectory of the install directory. You didn't say what kind of program you wrote, it is easy with Application.ExecutablePath in Windows Forms. But the generic solution that works everywhere:
public static string GetImagePath(string filename) {
string exeFile = System.Reflection.Assembly.GetEntryAssembly().Location;
string exePath = System.IO.Path.GetDirectoryName(exeFile);
string imgPath = System.IO.Path.Combine(exePath, #"images");
string imgFile = System.IO.Path.Combine(imgPath, filename);
return imgFile;
}
Which assumes the images are stored in a subdirectory named "images". Tweak as necessary.
Last but not least: don't forget that you can add images to your program's resources so it is baked in the .exe file. Project + Properties, Resources tab. Highly recommended.
You can also use predefined or existed system variable. Anyway you must decide when the user (or you) have to define that path (in config file or wherever) - during instalaltion, first run, before first run or in any time when app is running.
Personally I would use the Environment class in C#. Then I will locate the local app settings folder using the Environment.SpecialFolder enum.
I will then store all my applications specific files inside a folder in the local app settings folder.
This way you are also UAC safe, since UAC will complain if you want to store files in Program Files if you are not Administrator.

How to get the current directory on a class library?

I've been looking around but I have not found a solution for this problem: I want to create a class library that has a configuration file under a sub-directory called Configuration. I want that class library to be deployed anywhere and I want it to find its configuration files by knowing its own location.
Previous attempts with Assembly.GetExecutingAssembly().Location did not work.
It would return temp locations such as
C:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET Files\root\7c00e0a3\38789d63\assembly\dl3\9c0a23ff\18fb5feb_6ac3c901
instead of the desired
bin/Configuration path.
So:
Can a class library be aware of its own location on disk?
How would I go about witting test scripts for this functionality since it seems that directories change based on how you run the app (debugging inside VS, deploying on IIS, etc)
This should work -
string assemblyFile = (
new System.Uri(Assembly.GetExecutingAssembly().CodeBase)
).AbsolutePath;
The below code worked for me to get the physical path of the Images folder in-class library file.
string fullFilePath = Path.Combine((new System.Uri(Assembly.GetExecutingAssembly().CodeBase)).AbsolutePath.Split(new string[] { "/bin" }, StringSplitOptions.None)[0]
, "#/Images/test.png");
I hope, it will help someone.

Categories