Method Directory.GetDirectories failures - c#

Very odd that I am experiencing a occasional errors when calling the GetDirectories() method.
This started happening when our IT dept remotely moved some folders to my local machine. This error only occurs when navigating through these folders using C#.
Error Message: 'Access to the path 'C:\Users\XXXX\XXXXX is denied'
Code:
public static string[] GetDirectoryInfo(string path)
{
if (Directory.Exists(path))
{
//This call is failing on the new folder.
return Directory.GetDirectories(path);
}
return new string[0];
}
Not very complicated, correct?
Navigating with Windows Explorer, the folder isn't present.
In the CMD prompt I can change directory to this folder; following up with the DIR command I get the error 'File not found'.
I am guessing
the problem is a Win32 issue and something didn't get cleaned up when the folder was moved. I have no idea how to correct the issue, except for digging through decompiled System.IO classes; which I will do if I don't get a solution.

Your code is probably trying to access hidden folders that are not accessible to your account/role.
The easiest solution is to catch the UnauthorizedAccessException and just eat it, so it essentially skips the directory, like this:
public static string[] GetDirectoryInfo(string path)
{
if (Directory.Exists(path))
{
try
{
//This call is failing on the new folder.
return Directory.GetDirectories(path);
}
catch(UnauthorizedAccessException unAuthEx)
{
// Do nothing to eat exception
}
}
return new string[0];
}

This occurs when the software tries to access folders which have been restricted by the windows for security reasons like for example :
C:\Users\Default (This path is not accessible by your code)
Another reason would be that your application is trying to access folders which are not really folders like
My Music
My Pictures
If you are trying to read all the folders in a specific drive, then you can make some exception to handle these directories, another thing that MIGHT help you is to run your application as administrator.

Related

FileNotFoundException not caught when distributing app over network

I wrote a little WinForms app which reads settings from a file located in %APPDATA% on startup. If the settings file doesn't exist or is invalid, the program uses hard-coded defaults. And it all works fine, until I copy my app to another PC via network share or try to start it from a network share directly. Then the program silently terminates, and I keep getting a FileNotFoundException in the event log although I have a try/catch block and although the file even exists!
It feels like it's some sort of permission thing since it only happens when the app was distributed over a network share, even after I copied everything to a local folder (without any complaints from Windows). However, the program manages to create the folder for the settings file and crashes when trying to read the file afterwards.
When I copy the program to another PC using a USB drive, everything works fine. But that's a workaround I don't like, and it doesn't actually solve the problem.
So why does it throw a FileNotFoundException no matter whether or not the file exists? And why doesn't the exception get caught but terminates the program instead? How can I fix this?
The event log shows something like this:
Description: The process was terminated due to an unhandled exception.
Exception Info: System.IO.FileNotFoundException
at MyNamespace.Settings.Load()
at MyNamespace.Program.Main()
And here is some code snippets:
Program.cs
public static Settings Settings { get; private set; }
static void Main()
{
Settings = Settings.Load();
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new FormMain());
}
Settings.cs
public static readonly string FileName;
static Settings()
{
string directoryName = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "MyProgram");
FileName = Path.Combine(directoryName, "Settings.json");
Directory.CreateDirectory(directoryName);
}
public static Settings Load()
{
try
{
string json = File.ReadAllText(FileName);
return JsonConvert.DeserializeObject<Settings>(json);
}
catch
{
return new Settings();
}
}
All PCs are running on Windows 10 v1909. I'm using VS2019 Enterprise 16.6.5.
Well, this is kind of embarassing, but I thought I post the answer anyway.
I was just missing a referenced library, in this case Newtonsoft.Json.dll which was first used and therefore tried to be loaded during Settings.Load(). This caused the FileNotFoundException to be thrown and not be caught - because it wasn't my code throwing it.
When using network share distribution, I simply forgot to include this file for whatever reason. On the USB drive, I didn't. Thanks to Thomas Weller who pointed out that it could be a file other than my Settings.json, which I just didn't think about.

C# Program Permission Denied when reading files in windows or Users folders

I have a small program which I am writing to read folder sizes on a drive or in a specific folder.
I am admin user on my pc. But when I run the program it get Permission Denied e.g
"Access to the path 'C:\\Users\\tempuser\\AppData\\Local\\Application Data' is denied.
I am trying to get all files and folders so that I can calculate full size of the folder. But cant get through this permissions. I have used application manifest and tried "highestAvailable" and "requireAdministrator" both don't seem to do what I want, Can some one shed some light how do I run program so that I get almost true size of the folder?
Here is line of code which I am using
sizeInBytes = di.EnumerateFiles("*", SearchOption.AllDirectories).Sum(fi => fi.Length); //this works great only fails in folders such as above/users/windows etc
The above will just throw exception, I used following code to see where exceptions were being thrown
var finfoList = di.GetFiles("*", SearchOption.AllDirectories);
foreach (FileInfo finfo in finfoList) {
string fname= finfo.Name;
}
Thanks

C# Could not find a part of the path with Directory.GetDirectories

I'm trying to make an application that copies volume to a selected location in the computer.
The volume is an external hard disk that includes a copy of my previous computer C volume.
First of all, when I tried to copy the directories and the files I made an recursive function that gets the directories and the files and copy them to the new location, the recursive function gets the directories with Directory.GetDirectories function, after I get the sub directories I make the same function to get the sub directories of the sub directories and keeps doing that untill there are no directories to get, all works fine but when I tried to use the application on my volume I got an infiniate loop with "Application Data" folder, that means that the GetDirectories function found "Application Data" folder in the previous "Application Data" again and again.
In order to fix that I checked if the path does not include "Application Data\Application Data" and just the I used the GetDirectories function.
Maybe that solution caused the problem I'm going to ask about.
The problem is that when I use the function GetDirectories I get an exception: "Could not find a part of the path" but my code looks like this:
if(Directory.Exist(path))
{
string[] subdirs = Directory.GetDirectories(path);
}
So how is that possible that the Exist function finds the folder but the GetDirectories function does not find it?
By the way, the application works properly on directories that are not part of windows system.
So what is the problem? And how can I solve it or how can I make copy application that will copy C volume?
Thanks a lot
From Microsoft support:
A service that runs under a LocalSystem account or under a local user
account can only access mapped drives that the service creates. Mapped
drives are stored for each logon session. If a service runs under a
LocalSystem account or under a local user account that does not create
certain mapped drives, the service cannot access these mapped drives.
Additionally, a service that runs under a local user account that
creates certain mapped drives also receives a new set of mapped drives
if you log off and then you log on again as the same local user.
There is a workaround but it not necessary, just use try-catch for those libs:
if(Directory.Exist(path))
{
try
{
string[] subdirs = Directory.GetDirectories(path);
}
catch (Exception ex)
{
}
}
Or, alternatively, use Directory.GetDirectories SearchOptions so you can disclude certin sub-directories.

HttpPostedFile.SaveAs access denied

I'm trying to save a file that I upload from my page but I'm getting an access denied error:
public void SaveFile(Item item, HttpPostedFileBase file)
{
var dir = string.Format(#"{0}\NSN\{1}", ConfigurationManager.AppSettings["ContentLocation"].ToString(), item.Id.ToString());
if (!System.IO.Directory.Exists(dir))
System.IO.Directory.CreateDirectory(dir);
Array.ForEach(Directory.GetFiles(dir), File.Delete);
file.SaveAs(dir);
}
I'm running this site from the local host from visual studio so no app pool is involved. I've given the Network Service (and Everyone as a test) full control of the folder and it's subfolders. Strange thing is it creates the folder if it needs to and also deletes any files in an existing folder. Only when I call the SaveAs function do I get the error.
You call file.SaveAs with path to directory instead of path to file
Here, give this a try:
string saveAsPath = Path.Combine(dir, file);
file.SaveAs(saveAsPath);
Replace file.SaveAs(dir) with the above.

Environment.GetFolderPath(Environment.SpecialFolders.ApplicationData) returns C:

I have encountered a very strange behavior on the computer of one of my clients and I cannot find any clue as to why it happens:
When the application calls Environment.GetFolderPath(Environment.SpecialFolders.ApplicationData)
the return value will be C:.
This is of course wrong, his AppData directory is the usual C:\Users\.....\AppData\Roaming and also his variable %APPDATA% points to exactly that directory.
Can anybody shed light on why this could possibly happen?
EDIT: The code...
LogFilePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) + #"\ReportsAddin";
if (!Directory.Exists(LogFilePath) && Properties.Settings.Default.Logging == true)
{
try
{
Directory.CreateDirectory(LogFilePath);
}
catch (Exception ex)
{
// ...
}
}
The exception thrown then says that it cannot create a directory consisting of a blank string or blank spaces. Investigating with some output showed that the AppData folder returning from that call is C: when in fact it should be the user's real AppData folder.
The actual path for the folder identified by Environment.SpecialFolder.ApplicationData depends on the current user (who started the program).
Make sure the program runs under a user account for which the ApplicationData folder exists.
If your program runs under e.g. a local system account you may want to use another directory.
Instead of Environment.SpecialFolder.ApplicationData you could use Environment.SpecialFolder.CommonProgramFiles or Environment.SpecialFolder.CommonProgramFilesX86.

Categories