C# Listing all directories in C:\ - c#

In my application every user can set his own save path to save his files and settings
so every time the user log in i must search a folder that contains the username+"Data"
for example if the user name was "Kim" i need to find the path to the folder KimData
when i try to get all directories in C:\ the UnauthorizedAcessException appears
so is there a way to search for that folder or just skip the unauthorized folders while searching ?

The UnauthorizedAccessExpection means that the caller does not have the required permission to access the directory/file. Since you're doing it locally, there are several options. After you attempt to copy the data from VS to the data in the file (Create, copy, delete) etc.... you can try File.SetAttributes(yourfile, FileAttributes.Normal).
You can also use Environment.GetFolderPath. Accordingly, this:
"Gets the path to the system special folder that is identified by the
specified enumeration, and uses a specified option for accessing
special folders."
Also, I'm guessing you're simply looking through the entire directory/folder/path all at once. A workaround would be to probe one directory at a time. This is assuming you are adding a file. Once you've found your directory, you can use:
Directory.GetFiles(path)
.ToList()
.ForEach(s => files.Add(s));
Directory.GetDirectories(path)
.ToList()
.ForEach(s => AddFiles(s, files));
EDIT: Some helpful related questions on stack to look at might be:
UnauthorizedAccessException
Directory.GetFiles

Take a look at Ignore folders/files when Directory.GetFiles() is denied access and see if it helps you.
However if you are trying to look for a specific folder - which according to your question the user can place anywhere - in the entire directory tree i advise against it as it probably will be slow.
I would recommend saving the path somewhere and reading it from there when the user logs back on.
If its a desktop app and each user runs the app with its own windows account an even better solution would be to always write the data to the user's ApplicationData folder which you can get with Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData).
As the name indicates this folder exists to keep applications data and its individual for the user logged in to windows

Related

How can I access files inside My User folder from the application?

I am creating an Windows Explorer kind of app using metro UI. I want to show content of a certain folder in my User folder.
I wanted to know if it is possible to access the folders and files inside users folder and how do I do it?
Edit :
I tried using StorageFolder. For documents folder, it gives me an exception.
The KnownFolders.DocumentsLibrary folder has restrictions on its use. You have to manually declare the capability in your manifest, declare specific file types you want to access, and then to publish the app in the Store you have to be using a company account (not an individual account), and have to submit written justification for your programmatic use of the folder.
See http://msdn.microsoft.com/en-us/library/windows/apps/hh464936.aspx as well as the note for section 6.6 of http://msdn.microsoft.com/en-us/library/windows/apps/hh921583.aspx.
Note that this is for programmatic access without user consent. If you use the file picker, the user can of course point to the documents folder thereby giving you permission to use it. But without that, you need to use your app data folders where you do have programmatic access.
The underlying reasoning here is that files that your app it generating for its own use, that don't have direct meaning to the user, should go in app data to avoid polluting a folder like Documents with stuff that the user doesn't know what to do with. For "user data" files--which the user does understand, you should give them the option to choose where those files go, hence the use of the file picker.
A few file types like music, pictures, and video have direct library access via manifest capabilities, but in that case the user generally understands that they're working with that kind of data.
You can access the contents of users folder like this:
string path = Directory.GetParent(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)).ToString();
Use SpecialFolder to get the user folder and Directory.Enumerate() for getting files in the folder.

Why am I getting a "Could not find a part of the path" exception?

I am developing website using Visual Studio 2010. I am trying to save a file in a path. It works fine localhost.
But the same code is not working in IIS. It shows the following error
Exception Details: System.IO.DirectoryNotFoundException: Could not
find a part of the path 'C:\Inetpub\wwwroot\Vendor\cn.jpg'.
Could not find a part of the path 'C:\Users\shashank\Desktop\ab.csv'.
Here is the code:
protected void btnImportFile_Click(object sender, EventArgs e)
{
sArReportText = File.ReadAllText(txtFilePath.Text.Trim());
// Set the report Properties to insert Report information
SetProperties();
}
You might also be experiencing what I am: that the directory name contains some unusual characters. In my case,
Could not find a part of the path 'C:\Web\metBoot\wild iis\DigiCert© Certificate Utility for Windows_files'.
That copyright sign is the issue.
So using concepts drawn from Obtaining the short 8.3 filename from a long filename, I convert my paths to short form first, then use that to get my list of files.
StringBuilder sf = new StringBuilder(300);
int n = GetShortPathName(sourceFolder, sf, 300);
if (0 == n)
{
tk.write(Marshal.GetLastWin32Error().ToString());
continue;
}
...
IEnumerable<string> fileGroup = Directory.EnumerateFiles(sf.ToString(), ext);
Consider how you're launching VS too. Counter-intuitively I run into this problem only when I'm running VS in Administrator mode. Possibly a group policies thing.
This may be because, you are not having the specified file in web server, or you may be used an incorrect path. Specify the exact folder and filename as how it is stored in the web server. use HttpContext.Current.Request.ApplicationPath or Server.MapPath to specify the correct location where your desired file lies. And also make sure that you have given read and write permissions for this specific file and its folder.
You need to have permissions set in iis to allow files to be saved in the folder. Basically your uploaded files should be saved inside a separate folder present inside your root directory.
In order to access, create and delete files on the server, must have rights.
Like in my project I am using Impersonator class to access various files and folder from the server.
Otherwise it will throw an exception.
You could use code impersonation:
http://csharptuning.blogspot.com/2007/06/impersonation-in-c.html
http://www.codeproject.com/Articles/14358/User-Impersonation-in-NET
regardless, whomever you use as the impersonation must be able to read/write to the location that is being saved to. We use this method in applications for delete/create folders across network. Even if App_Data is best practice, it may be a business requirement to access the documents outside of that folder.
You can also set impersonation on IIS.
I also notice that your function is called btnImportFile. You may want to look into FileUpload control if you are uploading a file, which allows you to get the byte array of the file and save as needed. https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.fileupload%28v=vs.110%29.aspx. You might still need to use Server.MapPath or HttpContext.Current.Request.ApplicationPath depending on your needs.
It's usually best practice to use the App_Data folder to save files to.
Take a look here, Working with files, for a tutorial.

Get access to program's own directory

this is a very simple issue.
Note: I am sure people have found and posted this same issue somewhere but I can't figure out the correct search terms to find it.
Okay, so here is my issue.
Let's say my program is stored at C:\Program Files (x86)\MyProgram\Program.exe.
Now in the program, it basically does
Directory.CreateDirectory(Application.StartUpPath + "\\Files")
So basically, this would create a directory called Files in the same folder as the program itself.
Assume that I have to create the folder in that location, so using a different location is not an option.
So the real problem is, if its located in the c:\Program Files directory, my program gets "access denied" when I try to create the folder.
So how can I get something like this to work without forcing the user to run it as an admin?
If it's in Windows 7, if UAC is elevate, you won't be able to modify anything in c:\Program Files without rooting yourself via 'run as administrator'.
And since windows is a multi-user operating system, storing anything user-specific there is a recipe for disaster.
The right place for your program to put its data is in the appropriate special folder, which you can get/create via either
// user-specific application data is stored here
string userSpecificAppDataDirectory = Environment.GetFolderPath(
SpecialFolder.ApplicationData ,
SpecialFolderOption.Create
) ;
// application data common to all users is stored here
string commonAppDataDirectory = Environment.GetFolderPath(
SpecialFolder.CommonApplicationData ,
SpecialFolderOption.Create
) ;
or one of the other Environment.GetFolderPath() overloads.
In modern operating system the folder C:\program files (x86) is write protected by the OS. You can't create sub folders here without using an administrative account (and also in that case you will be asked to confirm this action unless you disable UAC). So the correct way to follow is to create your data folder in another place. The best option is the CommonApplicationData folder extracted using:
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData)
or the SpecialFolder.ApplicationData enum if your data should be differentiated by the current user of the application, or the SpecialFolder.MyDocuments if these files are produced by your user and need to be opened freely by other programs (or need to be included in a backup)
After you get the special folder provided by the OS to store application data remember to create a subfolder for your application and the other subfolders as required by your requirements
// In Win7 this usually resolves to C:\ProgramData, but do not use this folder
string appCommon = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData);
// This resolves to C:\programdata\your_app_name\files
string appData = Path.Combine(appCommon, "your_app_name", "files");
// This will create all directories in the specified path one by one....
if(!Directory.Exists(appData)) Directory.CreateDirectory(appData);
You could try creating any files or folders you need during your installation procedure. I am not sure what success you would find if using a third party install creator, but my understanding is that items added via the Application Files... button in the Publish tab of the Project Properties section in Visual Studio then have access privileges kind of inherently granted for use by the application.

Exclude Dir From path

I want to Get all dirs from my drive Excluding "System Volume Information"
The problem is i am sending args to another console application for compressing though. and i'd have to send only single path.
how to do that?
E.g.
command line of qpress.exe
qpress.exe -dvf ArchiveName.qp "SourceDir"
qpress.exe -dvf D:\Archive.qp G:\
i want to Exclude "System Volume Information" Folder from being Included in Archive
If you want to do it right and you have to send to your console application all directory names in your disk drive, let's say at the first/root level, you should not only hard code or exclude the folder "System Volume Information" because you cannot be sure there are not other folders for which you have no rights to read/open...
I think a good approach is to check every single folder name for read permissions ( or whatever other permission you might need to have on such folder in the console application you pass the foldername to ).
This is in general a good approach, to always verify if you can do a certain thing, for example before deleting a file, check if you can actually delete it. Or if you prefer, you could then catch the exception afterwards, but probably your external console application would crash so better check rights before calling it with a specific folder name.

Quick Question: How can I make sure the current directory is not changed because of OpenFileDialog?

say my application is installed in C:\programfiles\xyz\ I've some setting & other data files (*.dat files) in this directory too.
My application uses OpenFileDialog to open an image. Problem is that when ever user browses to some directory (say MyPictures) for an image. The current working directory of the application becomes that directory (MyPictures in this case).
After user inputs the image. I do some processing over it and save some values to imagedata.dat which will be located in the path where original application is installed.(C:\programfiles\xyz here )
In my code I'm just using FileStream("imagedata.dat",...,...) without any path prefix before the filename. Problem here is that application is crashing because it is searching for imagedata.dat in 'MyPictures\imagedata.dat'.
How can I avoid this?
You should be using absolute path names when saving data to files. The current working directory is controlled by the user, not by you (for example, if they launch your process from a shortcut then the working directory could've been changed before your process even starts up).
Also, you should never save anything under C:\Program Files during normal use. Doing this means your program needs to be running as an administrator, and unless you're doing administrator-y things then you should be able to run it as a regular user.
The correct thing to do in your case is to use the Environment.GetFolderPath() function to get the location of the ApplicationData folder and save your data under there. Just choose a sub-directory based on your application's name.
You could save it to GetCurrentDirectory then restore with SetCurrentDirectory. However, I agree wih codeka that using the appropriate GetFolderPath (probably ApplicationData, CommonApplicationData or LocalApplicationData) is a better solution.

Categories