The project I am working on gets configuration by pointing at a folder, in the past the was done by a relative path (e.g. "../../api/data/"), however this was not suitable in all cirumstances as depending on assembly location the relative path to the above would be different, so another method was devised using
System.Reflection.Assembly.GetExecutingAssembly().Location
Ideally we would combine part of the path received from the above with the destination using path.combine() so if the full destination path was "Folder/Core/api/data" and the result from GetExecutingAssembly() was "Folder/Core/Assembly/Assembly.dll", then the plan was to take everything before "/Assembly/" using something like
assemblyPath.Substring(0, assemblyPath.IndexOf($"/Assembly/"))
then combining the result with "../../api/data/" to get the full path.
However I can see now that this will not work if the assembly path is different and does not contain /Assembly/. So I am now wondering what is the best way to dynamically get the full path. I thought about using a switch statement based on the deployment, however that is not very futureproof.
Related
I’m trying to save file to D:\folder1\folder2\file.txt using the following logic:
public void ChangeBackground(ChangeBackgroundDto dto)
{
var dir = Directory.GetCurrentDirectory();
File.WriteAllBytes("../../Images/Custom/BackgroundHome.png", dto.BGFileFormat);
}
However, when I do this, I recent an exception because I have root directory at C:\programfiles(x86)\llsExpress.
The exception message is: Could not find a part of the path 'C:\\Images\\Custom\\BackgroundHome.png'.
What path which will work for this even when I deploy the application?
First I'd suggest you to try to store your file in a relative path in the root folder if possible. This helps with security plus you'll know that all the files for your site are in the root folder.
If you really want to store files on a different drive, you cannot use relative paths to do this. So no .. in your paths. You'll have to use the absolute path. Store that somewhere in config or environment variables to avoid configuring file paths hard coded.
Finally please use code blocks to show code rather then screenshots on StackOverflow.
You can do this by putting the code as text between these chars ``. like this
Say, I have two path strings, an absolute one such as #"C:\abc\xyz", and a relative one such as #"..\def". How do I reliably combine those to yield the minimal form #"C:\abc\def"?
As the process should work for any forms of path that .NET's I/O API supports (i.e. the native paths of the system that .NET or Mono is currently running on, or alternatively something like UNC paths and the like), manual string manipulation seems to be too unreliably a solution.
In general, the tidy way to combine path strings is to use the Path.Combine method:
Path.Combine(#"C:\abc\xyz", #"..\def")
Unfortunately, it does not minimize the path and returns C:\abc\xyz\..\def.
As is suggested in a couple of other questions (e.g. this, or this), the GetFullPath method should be applied to the result:
Path.GetFullPath(Path.Combine(#"C:\abc\xyz", #"..\def"))
The problem with this is that GetFullPath actually looks at the file system rather than just handling the path string. From the docs:
The file or directory specified by path is not required to exist. (...) However, if path does exist, the caller must have permission to obtain path information for path. Note that unlike most members of the Path class, this method accesses the file system.
Therefore, GetFullPath doesn't work if I just want to minimize arbitrary path strings: Depending on whether the path happens to exist on the system where the application is running, the method might fail with a SecurityException if the user does not have access to the path.
So, how do I reliably combine path strings that could be processed by System.IO methods to return the shortest possible absolute path?
You can use AbsolutePath of Uri class
var path = new Uri(Path.Combine(#"C:\abc\xyz", #"..\def")).AbsolutePath;
If you want to use it via System.IO you will run into access violation problems at that point.
Why bother to increase the time till the exception comes?
Use try {} catch {} around GetFullPath and handle the error in place would be my suggestion.
So, how do I reliably combine path strings that could be processed by System.IO methods to return the shortest possible absolute path?
I am trying to do is to get filepath for my excel file. But I am unable to do so.
File is in Document/Visual Studio 2013/Project/ProjectName/a.xlsx
string path = Path.Combine(HttpContext.Current.Server.MapPath("~/"),"a.xlsx");
string SheetName="Sheet1";
Is it wrong way to do it or is it correct way?
This is the better answer according to me.
Better to save in
C:\Users\AJ1110\Documents\Visual Studio 2013\Projects\Proj\Proj
And in
program.cs
string pathfile = #"..\..\a.xlsx";
string sheetName = "Whatever_SheetName_IS!!!";
This might solve your problem.
HttpContext.Current does not work outside of a web context.
If your project is running inside a console or windows program, it cannot work with HttpContext.Current. MapPath is meant to translate a web path to a file system path. ~/ is a .Net convention for pointing the root web path of a web application.
You should explicit what are your requirements about how to resolve the folder containing your file.
Maybe should you simply put that in some configuration file (using settings property tab of the project by example) and retrieve it from there.
Edit:
So, from your comment on this question, it looks like you have to seek the xl file in the executing folder.
There is a number of ways for achieving this, depending on your application use cases.
By example, check this question.
Since your project is not a Web one, I expect that you some sort of Output where build process generates an executable file, some assemblies etc. You can put Build action of your Excel as Content (more details here) and use this base path to retrieve it:
System.Reflection.Assembly.GetExecutingAssembly().Location
It is important to think in terms relative to your executable (or executing assembly to be more precise), since your output will have to run outside your development environment and your excel must still be accessible.
Also, getting the exact executing assembly might be tricky in some scenarios.
i have a small app in C# winform. It work great but i don't understand how to change the image of a picture box in code :
i have this directory for my image :
myProjectDirectory/bin/Pics/myImage.jpg
and this code give me an FileNotFoundException :
this.imgInvader.Image = Image.FromFile("../Pics/invader2.jpg");
i don't understand because i see on stackoverflow that FromFile method begin at bin/Release. So a ../Pics/myImage.jpg should work no ?
Thx
Use the relative path of the image.
this.imgInvader.Image = Image.FromFile(#"bin\Pics\invader2.jpg");
Here give the path from the location where your code behind file is located. Suppose if your file is in root directory and if your images are in bin/Pics/ folder then the above code works. It automatically gets the path related to the location the program is running from.
Trying to reference image files that are outside the executable output directory is incredibly fragile. There are lots of ways it can go wrong (unfortunately, there's not enough context in your question for anyone to know exactly which of these ways is your specific problem).
If you must use files on disk to store your image resources, then they should be copied into the build output directory (i.e. "Release") and referenced there. Add the file to your Visual Studio project, select it, and in the properties window, set the "Build Action" value to "Content". If the file is in a folder under the project, then it will also be copied to a folder of the same name in the output directory.
If you do use files on disk, the other thing to make sure you do is find the executable's directory (e.g. via Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)) and then combine that with your expected relative path (e.g. just the file name, or the file name under whatever folder/subdirectory you gave it in the project, if you did) using the Path.Combine() method, and then using that absolute file name as the source. Otherwise, your code can be confused by changes in the current directory made elsewhere in your program (basically, don't ever rely on the current directory…global state like that is too easy to get mixed up, once you get into the habit of using it).
For example:
string exeDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
string imageFileName = Path.Combine(exeDirectory, "invader2.jpg");
Now, all that said, IMHO it is probably a better idea to add your images as resources in the executable itself, and then reference them from the Properties.Resources class. Then the images are always with the executable, because they are in the same file. The code is a lot easier too, because you're just referencing properties in the Resources class that return the actual Image objects you need.
As the previous comment stated, using resources outside of your exe is not advised however you can still do this by using the Path.GetDirectoryName Method.
I am left to question why your resources are based outside of your exe, why not embed it into your resources located in properties > resources.resx and simply call it with imgInvader.Image = Properties.Resources.FileNamehere; it is a lot safer than trusting the external environment.
When I run SomePicturebox.Load("Foo.bmp") and there is a Foo.bmp in the application's startup folder, it will load this image. However I have a case where the image is not loaded (when the application is started by an installer, namely).
Now I am wondering: Is there a default path that is searched by the framework when the path is not fully qualified? How can I show this path at runtime (to reveal why the image is not loaded in some cases)?
I tried looking at the Picturebox.ImageLocation property but this said just "Foo.bmp" without a path.
This is related to WinForms, .NET Framework 4.
Answers in both C# and VB.NET are very welcome.
In VB.NET
Dim directory as String = My.Application.Info.DirectoryPath
In C#
string directory = AppDomain.CurrentDomain.BaseDirectory;
I tested and AlexC was correct and I have updated this answer.
The best way to get the current value for the path is with System.IO.Directory.GetCurrentDirectory().
Rather than dealing with this ambiguity, though, it is better to make sure you fully qualify the path. To get paths on a system that can change, you should use the System.Environment.GetFolderPath call. For example, if you want the user's documents folder:
var path = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
If you happen to be using an open file dialog the following is another call I often find helpful:
var fullPath = System.IO.Path.GetFullPath(selectedFile);
There are quite a few other routines in the System.IO.Path namespace that can help you with making sure that your file and path names are always fully qualified. Hope these help!
Note - My answer is in C#