How to get current windows directory e.g. C:\ in C# - c#

As the title suggests, how can you get the current OS drive, so you could add it in a string e.g.:
MessageBox.Show(C:\ + "My Documents");
Thanks

Add a reference to System.IO:
using System.IO;
Then in your code, write:
string path = Path.GetPathRoot(Environment.SystemDirectory);
Let's try it out by showing a message box.
MessageBox.Show($"Windows is installed to Drive {path}");

When looking for a specific folder (such as My Documents), do not use a hard-coded path. Paths can change from version-to-version of Windows (C:\Documents and Settings\ vs C:\Users\) and were localized in older versions (C:\Users\user\Documents\ vs C:\Usuarios\user\Documentos\). Depending on configuration, user profiles could be on a different drive than Windows. Windows might not be installed where you expect it (it doesn't have to be in \Windows\). There's probably other cases I'm not aware of.
Instead, use the Shell API (SHGetKnownFolderPath) to get the actual path. In .NET, these values are easily obtained from Environment.GetFolderPath. If you're looking for the user's My Documents folder:
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
Full list of special folders

You can use Environment.CurrentDirectory to get the current directory. Environment.SystemDirectory will give you the system folder (ie: C:\Windows\System32). Path.GetPathRoot will give you the root of the path:
var rootOfCurrentPath = Path.GetPathRoot(Environment.CurrentDirectory);
var driveWhereWindowsIsInstalled = Path.GetPathRoot(Environment.SystemDirectory);

If you don't mind a little parsing: Environment.SystemDirectory returns the current directory.

Related

C# SpecialFolders enumeration does not include Libraries Folder

The question title is seemingly straight forward and self-explanatory. The issue is that the SpecialFolders enumeration does not include Libraries Folder and I really need to access it and display its folders in a ListBox. Is there any way to do this please?
The path to the Libraries folder is %APPDATA%\Microsoft\Windows\Libraries, you can use SpecialFolder.ApplicationData, which on Windows is the same as the %APPDATA% environment variable:
var appData = Environment.GetFolderPath(
Environment.SpecialFolder.ApplicationData);
var librariesFolder = Path.Combine(appData, #"Microsoft\Windows\Libraries");
Another way to get the full path is to just expand the environment variable:
var librariesFolder = Environment.ExpandEnvironmentVariables(
#"%APPDATA%\Microsoft\Windows\Libraries");
Anyways, this is Windows specific and won't work on other platforms, which is pretty much the single good reason to use Environment.SpecialFolder in the first place.

is there any way to make System.IO.Directory.GetFiles(string) look in the program's directory?

I'm trying to use string[] files = System.IO.Directory.GetFiles("~/Pictures/"); to search a folder in the program for picture files. This will later be used to randomly select a picture to display in an image box.I get an error when it tries to find ~/Pictures because the method is looking in 'C:\Program Files (x86)\Common Files\Microsoft Shared\DevServer\10.0\~\Pictures\'. instead. Isn't the "~" going to make it look in the programs directory? How do I make it look in the programs directory if I don't know what it will be until the program is installed? Any help will be appreciated!!
The tilde path is an asp.net construct that represents the root of the currently running asp.net application. It has no meaning outside of the asp.net context -- Directory.GetFiles doesn't know how to work with it. GetFiles does know how to work with a regular filesystem path. So the question becomes: How do we translate the asp.net relative path to one GetFiles can work with. The answer is HttpContext.Current.Server.MapPath.
I'm not near my webserver right now, but something like
var serverPath = HttpContext.Current.Server.MapPath("~/Pictures/");
var files = Directory.GetFiles(serverPath);
should get you started.
I don't think you'll find the "~" has any significance.
Try Application.StartupPath
Supplying a relative directory, like "Pictures", instead of "~/Pictures/", should do the trick.
Just use System.IO.Directory.GetFiles('Pictures'). The path separator on Windows is \, not /, and directories below the current one are just referenced as relative path locations.

Checking the existence of a file using relative path

What is the best way to check the existence of a file using relative path.
I've used the following method but it returns false despite the fact that file is existing.
bool a = File.Exists("/images/Customswipe_a.png");
That's not a relative path. You need to leave off the first / otherwise it will be interpreted as being rooted (i.e. C:/images...)
I guess that you are running this code in asp.net application, thats why you get false.
In asp.net you should use Server.MapPath("/images/Customswipe_a.png") to get "correct" path (relative to the web application root directory). Otherwise you get path local to the webserver executable (IIS/WEBDAV/..name any other).
The relative path is relative to the current working directory. It may not be the application directory. Call GetCurrentDirectory() to check the actual path you are testing.
You just need to define what your file is relative to
Your application main assembly?
Current directory?
Application data directory?
name it...
In each of these cases I'd suggest you to convert it into an absolute path by Path.Combine method:
public static readonly string AppRoot = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
...
//calling with a '/' heading makes the path absolute so I removed it
var fullPath = Path.Combine(AppRoot, "images/Customswipe_a.png");
var exists = File.Exists(fullPath);
This way you can guarantee where you are looking for. Even the Open/Save file dialogs may change your current directory. So, calling File.Exists without full path is usually a wrong decision.
You can test this path with System.IO.DirectoryInfo:
DirectoryInfo info = new DirectoryInfo("/images/Customswipe_a.png");
string absoluteFullPath = info.FullName;
As Mike Park correctly answered this path is likely to be (i.e. C:/images...)
The relative path, is a relative to something.
In this API, it will, according to the documentation File.Exists:
Relative path information is interpreted as relative to the current
working directory.
So everything here is depends what is CurrentDirectoty at the moment of execution of this query.
Plus, your path is not valid Desktop path (I assume you pick it from some web file, or knowledge). To understand if specified path contains not valid characters use GetInvalidCharacters function.
In your specific case it would be enough to use #"\images\Customswipe_a.png".
The path is relative to the location of your binary file. In the case of a visual studio project, this would be %PROJECTDIR%/bin/(RELEASE||DEBUG)/
What I would do is put the filesystem root in a config file, and use that for your relative path.
In a WinForms application you can get the directory of the exe file with
string directory =
Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath);
Another solution uses Reflection
string directory =
Path.GetDirectoryName(Assembly.GetEntryAssembly().Location);
As of .NET Core 3.1, this works:
Use dependency injection to include service IWebHostEnvironment
private IWebHostEnvironment Env;
public MyController (IWebHostEnvironment env){
Env = env;
}
Then use it to get path to root of app with Env.ContentRootPath
And combine it all:
var file = System.IO.Path.Combine(Env.ContentRootPath, "images", "some-file.png");

C# File Handling: Create file in directory where executable exists

I am creating a standalone application that will be distributed to many users. Now each may place the executable in different places on their machines.
I wish to create a new file in the directory from where the executable was executed. So, if the user has his executable in :
C:\exefile\
The file is created there, however if the user stores the executable in:
C:\Users\%Username%\files\
the new file should be created there.
I do not wish to hard code the path in my application, but identify where the executable exists and create the file in that folder. How can I achieve this?
Never create a file into the directory where executable stays. Especially with the latest OSes available on the market, you can easily jump into the security issues, on file creation.
In order to gurantee the file creation process, so your data persistancy too, use this code:
var systemPath = System.Environment.
GetFolderPath(
Environment.SpecialFolder.CommonApplicationData
);
var complete = Path.Combine(systemPath , "files");
This will generate a path like C:\Documents and Settings\%USER NAME%\Application Data\files folder, where you guaranteed to have a permission to write.
Just use File.Create:
File.Create("fileName");
This will create file inside your executable program without specifying the full path.
Don't forget to add:
using System.IO;
You can get the full path to your new file with:
string path = Path.GetDirectoryName(Application.ExecutablePath) + "\\mynewfile.txt"
string path;
path = System.IO.Path.GetDirectoryName(
System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase );
MessageBox.Show( path );
http://msdn.microsoft.com/en-us/library/aa457089.aspx
In modern operating systems, the accepted answer of:
var systemPath = System.Environment.GetFolderPath(
Environment.SpecialFolder.CommonApplicationData
);
var complete = Path.Combine(systemPath , "files");
will produce a user agnostic path like: "C:\ProgramData\files"
To produce a user-based path similar to: "C:\Documents and Settings\%USER NAME%\Application Data\files"
You should use SpecialFolder.ApplicationData or SpecialFolder.LocalApplicationData instead.
I like to give the user the choice. I would default the directory to something like Environment.SpecialFolder.CommonApplicationData and let them read and edit the path at will. If in a console app display the path in help and allow them to pass it via command line argument.
This saves them the hassle of hunting for the folder. If they point to a path you cannot write to then you throw the error and let them decide what to do.

How to determine a full path of a named folder?

I want to determine the full path of certain folders. In my array, I just have the names of the folders, but when my application will get installed on another user's machine, my program must be able to determine the full-path of these folders.
How to get the fullpath?
You can check the method Path.GetFullPath, it could be useful to what you're trying to do.
Path.GetFullPath Method
Did you mean the My Documents folder and the rest? It's not obvious for me from your question.
The My Documents folder is:
Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
And the rest of the special system folders can be retrieved in a similar way.
By prefixing it with another Path. Which Path depends on your application.
string path = ...
string fullPath = System.IO.Path.Combine(path, folderNames[i]);
You could take a look at Environment.GetFolderPath(...)
Sounds to me that you mean actually the current path plus an additional path. I.e., suppose your application is installed in c:\installations and you need the relative path of resource\en-US, you want to find c:\installations\resource\en-US.
Normally I would go for getting the current path, but in Windows it is possible to start an application as if it is executing from a different path. A fool-proof way of getting the path of the current application (where it is installed) is as follows:
// gets the path of the current executing executable: your program
string path = Assembly.GetExecutingAssembly().Location;
// transform it into a real path...
FileInfo info = new FileInfo(path);
// ...to make it easier to retrieve the directory part
string currentPath = info.Directory.FullName;
Now it becomes trivial to get new paths.
string someRelativePath = #"reource\en-US";
string someFullPath = Path.Combine(currentPath, someRelativePath);
I know, it looks a bit contrived, but it is safer then using the current path.
FileInfo.FullName, if you are lucky and the constructor finds your file somehow (e.g. current working directory).

Categories