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#
Related
I hope I'm doing something wrong because to me at this moment it looks like what I'm doing is correct. First off I want to open a file using the name space.
Lets say I have this string:
string resource = "Middelware.DataResources.dba.Queries.getTest.sql"
Then I'm trying to open it using:
var stm = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource)
But it doesn't work unfortunately. So I have been using this as a test case:
if (File.Exists(#"C:\text.txt"))
But for some reason it keeps returning false. I played around abit as well like using: "C:\\text.txt". But nothing happens.
I'm using visual studio 2017. And the class this is happening in is static.
So my questions:
Why cant file.exist seem to validate the test file exists?
Why is
var stm = Assembly.GetExecutingAssembly().GetManifestResourceStream(resource) not working, given that the namespace should be correct?
Hope some can help me with this silly problem.
Kind regards
You are not providing too much information so I'm guessing.
Read from file
From File.Exists method reference, the returned value can be:
true if the caller has the required permissions and path contains the name of an existing file; otherwise, false.
This method also returns false if path is null, an invalid path, or a zero-length string.
If the caller does not have sufficient permissions to read the specified file, no exception is thrown and the method returns false regardless of the existence of path.
You have already excluded some cases, so you should check whether the application has proper read permissions for the target file or its parent directory.
Read from assembly
Issues with resource streams are often related to:
Wrong resource name. Can be the upper/lower case, or an additional string put as prefix by Visual Studio compiler.
Resource not actually compiled in assembly
You can list all available resources in your assembly with:
Assembly.GetExecutingAssembly().GetManifestResourceNames()
Answer question 1: I had a typo..
Question 2 Is given in the comments. Let me quote:
Have you changed the type of the sql script to 'Embedded Resource' in the IDE? – Matt 3 mins ago
I am loading an image in my program with this code:
Image img = new Bitmap(#"C:\Users\******\Desktop\*****\bin\Debug\image.png");
I would like to keep the location static so I don't have to manually edit the path when I run the program on a different PC.
I am experimenting with the apps.config file as I have heard this is where my solution will lie.
Any help with this would be appreciated!
Why not use Environment.SpecialFolder?
This isn't static, obviously, but you wouldn't have to edit anything. You would really only have to create the folders on the desktop if they don't already exist.
string path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
Or use System.Environment.CurrentDirectory since it looks like that's where you're putting it anyway...
Image img = new Bitmap(Environment.CurrentDirectory + #"\image.png");
A better solution would be to embed it in a resx file as part of your assembly. That way you wouldn't have to worry about the file being located any differently.
The static property
AppDomain.CurrentDomain.BaseDirectory
points to the path from where the application was started, even if the current directory points somewhere else. You can use this to locate files that are in the same directory as the executable. However, for small images (i.e. GUI components), embedding them as resources is the way to go.
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.
I have the following scenario (C#, WinForms). I have some kind of project file which is saved in some directory. The project file contains a reference to another file. This reference is relative from the place where the project file is saved.
Sample: The project file is saved under c:\projects\project.xyz. The other file is referenced as "\someotherdir\file.abc".
This works fine, but there may be the case someone tried to manipulate that relative path to something like "..\Windows\System32\file.abc". So there's a need to check whether the relative path points outside the path where the project is saved (it's a defined requirement, that all referenced files are inside the project path).
How to detect this scenario?
You could try using the following extension method:
public static bool IsChildOf(this string path, string parentPath)
{
return Path.GetFullPath(path).StartsWith(Path.GetFullPath(parentPath),
StringComparison.InvariantCultureIgnoreCase);
}
Not very pretty but I think it should work.
if (System.IO.Path.GetFullPath(path).IndexOf(projectPath, StringComparison.CurrentCultureIgnoreCase) == -1)
{
// naughty
}
Edited to be a good global citizen.
Windows has posix symlinks: ln -s c:\windows\system32\mshtml.dll c:\projects\project.xyz\innocent.txt. When your program opens c:\projects\project.xyz\innocent.txt you get c:\windows\system32\mshtml.dll. Does System.IO.Path.GetFullPath() work here?
POSIX also supports hardlinks. A file can have zero (when deleted), one, two, ten, one hundred filenames. And all are "The Filename", none more correct or less correct than any other.
Windows supports mounting folders into folders. Again, all names are correct.
You can solve this with filesystem permissions: Create a new user for your application. Give that user permissions to your project path. Do not give that user (or Everyone, or any groups the user is a member of) privileges to anything else in any filesystem. Let Microsoft's kernel team solve your problem for you.