C# File Permission Exclusion - c#

I was wondering if there is a way to solve the issue I have with this code:
DriveInfo[] dDrives = DriveInfo.GetDrives();
foreach(DriveInfo dDrive in dDrives)
{
try
{
string sDrive = dDrive.ToString();
string[] sSearch = Directory.GetFiles(sDrive, sFile, SearchOption.AllDirectories);
foreach(string sResult in sSearch)
{
textBox2.Text = sResult + Environment.NewLine;
}
}
catch
{
}
}
When it comes across a file that isn't accessible because of permissions, it will goto the catch and end. What I need it to do is if it comes across a file it can't access, go back to the try block and continue searching. Any help is much appreciated, thanks!

EDIT:
Removed original answer as incorrect.
See: UnauthorizedAccessException cannot resolve Directory.GetFiles failure for some suggested resolutions to your problem.

The code you have should work, though you really should rethink your logic, using exceptions for flow control is plain wrong.
This will work, though not best practice:
string sDrive = dDrive.ToString();
try
{
string[] sSearch = Directory.GetFiles(sDrive, sFile, SearchOption.AllDirectories);
}
catch {}
foreach(string sResult in sSearch)
{
textBox2.Text = sResult + Environment.NewLine;
}
Where exactly are you accessing files? I only see a call to list file names (Directory.GetFiles), and listing of the file names returned.

Related

Illegal Character in Path when creating folders

I have a program that mass creates directories based on a CSV file. It runs through the loop but then it hits an "invalid characters in path" I need a validation (or if statement) to validate the folderName first and if it's invalid -reports it in a log file, then just proceed with the next folder creation.
StreamWriter sw = new StreamWriter(targetdir + "log.txt");
try
{
string[] items = File.ReadAllLines(csv);
foreach (string item in items)
{
Directory.CreateDirectory(targetdir + item);
sw.WriteLine(item + " OK!");
}
MessageBox.Show("Done");
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
sw.Close();
I'm not sure where to start. I feel like i have to add an "if else" but i'm not sure what to put. Thanks in advance.
The main change you need to do in your code is stopping concatenating together the variables that creates the destination folder and start using the Path.Combine method.
In your specific case you could use GetInvalidFileNameChars to have a list of characters not allowed to be part of a path or file name and then check if the current item contains any of those characters.
But there are other important changes to do.
First a StreamWriter is a disposable object and thus you should always create it inside a using statement to have a correct cleaup of its internal resources when you have done with it or even if an abnormal exception occurs.
Second, it is better to use File.ReadLines instead of loading all the lines in memory with ReadAllLines
char[] invalidChars = Path.GetInvalidFileNameChars();
string logFile = Path.Combine(targetdir, "log.txt");
try
{
using(StreamWriter sw = new StreamWriter(logFile))
{
foreach (string item in File.ReadLines(csv))
{
if(item.Any(x => invalidChars.Contains(x)))
sw.WriteLine(item + " BAD");
else
{
Directory.CreateDirectory(Path.Combine(targetdir,item));
sw.WriteLine(item + " OK!");
}
}
}
MessageBox.Show("Done");
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
Finally, I want to underline that in this context it is important to use GetInvalidFileNameChars and not GetInvalidPathChars because here we are checking the name of a folder. This name has the same rules used for files.
GetInvalidPathChars omits some characters that are valid in a path string like the \ or the ? and *. So for example GetInvalidPathChars doesn't have any issues with something like C:\Windows\System32\*.dll while this string contains characters not usable for a filename or for a single folder's name.

Exclude System Hardlinks from File.Copy

So my problem is that I want to export my user account.
But inside C:\%user%\AppData\Local\ are System Hardlinks e.g.: Application Data which I obviously have no right to use them.
Is there a way to exclude those System Hardlinks from the copying process?
I'm not sure what you mean with hard links, but this might help you
foreach (var dir in new DirectoryInfo(#"c:\users\xxxxxx\AppData\Local").GetDirectories())
{
if (dir.Attributes.HasFlag(FileAttributes.ReparsePoint))
{
Console.WriteLine(dir.Name + " is symbolic, skip it");
}
else
{
//do your copy here
}
}
So I fixed the issue with Exception handling, doing it this way:
FileInfo[] sourceFiles = null;
try {
sourceFiles = new DirectoryInfo(sourcePath).GetFiles();
} catch (Exception ex) {
WriteLog(LogPath, ex + "");
return;
}
Since I'm a bit new to exception handling, I couldn't work it out for the first few hours on this problem.

Getting "Could not find part of the path" error

im working on a project and what i try to do is to delete the
files in my folder.
but I get the error:
Could not find part of the path.
The problem is that the path have a ' which does make part of the path. Here is my code:
foreach (var a in attachments)
{
string[] files = System.IO.Directory.GetFiles(Server.MapPath("~/Files/'"+ a.FileName +"'"));
foreach (string pathfile in files)
{
System.IO.File.Delete(pathfile);
}
}
the result path is this:
'c:.....\Files\'14d75c4e-c25f-4288-9a75-08a359fe6d844.png'"
How can I solve this?
You don't need single quotes.
string[] files = System.IO.Directory.GetFiles(Server.MapPath("~/Files/"+ a.FileName));
This is because your code has extra (un needed) single quotes.
....MapPath("~/Files/'"+ a.FileName +"'"));
Change this line;
string[] files = System.IO.Directory.GetFiles(Server.MapPath("~/Files/'"+ a.FileName +"'"));
to
string[] files = System.IO.Directory.GetFiles(Server.MapPath(string.Format("~/Files/{0}", a.FileName));
Notice the change at the end of the code snippet(s).
Also, if I could suggest, wrap this in a Try / Catch (this would will help any future debugging as well).
Hope this helps.
Finally i have solved it.
the problem was the path and what i have done was little
different what i had before.
i have create a method to return the root path.
And then i have add it a simple variable and execute the
delete command.
Here is my code:
Method:
private string StorageRoot
{
get { return Path.Combine(System.Web.HttpContext.Current.Server.MapPath("~/Files/")); }
}
Delete Command:
foreach (var a in attachments)
{
var myfilename = a.FileName;
var filetoDelete = StorageRoot + myfilename;
System.IO.File.Delete(filetoDelete);
}
Hope this solution helps someone in the future.

Get directories and files with recursion?

Is possible to get all directories, subdirectories and files with recursion.
I do this because i want to increase my programming logic, and learn how recursion work.
I know to do that with this way:
string path = "D://";
string rezdir,newpath;
DirectoryInfo di = new DirectoryInfo(path);
DirectoryInfo[] dir = di.GetDirectories().ToArray();
for (int i = 0; i < di.GetDirectories().Length; i++)
{
Console.WriteLine(dir[i].ToString());
}
Console.WriteLine("\n\nChoose File: ");
rezdir = Console.ReadLine();
newpath = path + rezdir;
di = new DirectoryInfo(newpath);
dir = di.GetDirectories().ToArray();
for (int i = 0; i < di.GetDirectories().Length; i++)
{
Console.WriteLine(dir[i].ToString());
}
Console.ReadKey();
But i don't do that with recursion way, so ff someone can to do this, i'll be grateful to him.
Going by the code you posted - you seem to want some user interaction - so try something like this:
public static class RecursiveTest
{
public static string Foo(DirectoryInfo currentPath)
{
if (!currentPath.Exists) return string.Empty;
foreach (var directory in currentPath.EnumerateDirectories())
Console.WriteLine("Directory {0}", directory.Name);
foreach (var file in currentPath.EnumerateFiles())
Console.WriteLine("File {0}", file.Name);
while(true)
{
Console.WriteLine("Choose directory or file: ");
string chosenPath = Console.ReadLine();
string newPath = Path.Combine(currentPath.FullName, chosenPath);
if(Directory.Exists(newPath))
return Foo(new DirectoryInfo(newPath));
if(File.Exists(newPath))
return newPath;
Console.WriteLine("File {0} doesn't exist!", newPath);
}
}
}
And call with something like this:
class Program
{
static void Main(string[] args)
{
Console.WriteLine(RecursiveTest.Foo(new DirectoryInfo(#"d:\dev")));
Console.ReadLine();
}
}
HTH
I will avoid coding, because this is a valuable learning exercise. Try completing it yourself: once you do, you'll know that you understand recursion.
To be recursive, a method needs to call itself. Imagine that a method
public static void ShowDirectory(int indentationLevel, DirectoryInfo path)
is already written for you. This makes it easier to write the body:
Get all files in the directory, and print their names in the loop
Get all directories in the directory, and show their content at the next indentation level. You need another loop for that.
The first step is a simple exercise in writing loops. The second exercise becomes easy, too, because you can think of the ShowDirectory as pre-written.
Yeah, it's possible. But I do recommend that you first take a grasp of what recursion is. To put it simply, a recursion has a one-time executing part, and many-time executing part. That one time triggers the many-time part.
In this question, the one-time execution part might be to get the list of all directories beneath the root directory.
Then for each directory, you get all the sub-directories and files. This is the many-times part. However, to run a batch of codes many times, you need to bundle them into a callable routine, or procedure, or method, or function, whatever you call it. Just code bundle.
public void DoDirectories()
{
// one-time part; get a list of directories to start with.
List<string> rootDirectories = Directory.GetDirectories("c:\\").ToList();
foreach (string rootDirectory in rootDirectories)
{
GetSubdirectories(rootDirectory);
}
}
public List<string> GetSubdirectories(string parentDirectory)
{
List<string> subdirecotries = Directory.GetDirectories(
parentDirectory, "*.*", SearchOption.TopDirectoryOnly).ToList();
foreach (string subdirectory in subdirecotries)
{
GetSubdirectories(subdirectory); // recursing happens here
}
return subdirecotries;
}

Read permission on file denied

I have a problem with reading a bunch of files using the following C# code in my VS2008 project
public void FindFiles()
{
//Root
targetPath = Directory.GetDirectoryRoot(Directory.GetCurrentDirectory()) + "WriteToCSVFolder";
}
public void ReadFiles()
{
fileNameList_Original = Directory.GetFiles(targetPath);
string defaultFileName = "file_";
int counter = 0;
foreach (string fileName in Directory.GetFiles(targetPath))
{
fullFileText_Original[counter] = File.ReadAllText(targetPath);
//fileNameList_Original[counter]
counter++;
}
counter = 0;
}
Now please consider im just fast ticking this so I haven't bothered doing optimizations or anything yet. Just noticed that when I do a read action with the files NOT open and UAC (user account control) disabled on W7 64bit , and also not sharing it over network dropbox or anything else. It's just some ABC BLA FOO files I just made and wanted to test, they are in the correct directory marked targetpath in my system folder and the program is being run from the correct drive.
Is it just something stupid in the code or?
And oh yeah , the application was marked as full trust.
Any ideas?
EDIT:
With the new idea implemented from the comment section below:
Changed the code from
public void ReadFiles()
{
fileNameList_Original = Directory.GetFiles(targetPath);
string defaultFileName = "file_";
int counter = 0;
foreach (string fileName in Directory.GetFiles(targetPath))
{
fullFileText_Original[counter] = File.ReadAllText(targetPath);
//fileNameList_Original[counter]
counter++;
}
counter = 0;
}
TO
public void ReadFiles()
{
//Store all files names in a string array in one go
fileNameList_Original = Directory.GetFiles(targetPath);
string defaultFileName = "file_";
int counter = 0;
foreach (string fileName in Directory.GetFiles(targetPath))
{
//removed the storing file names, was redundant
//added the suggested idea to the proper array
fullFileText_Original[counter] = File.ReadAllText(fileName);
//fileNameList_Original[counter]
counter++;
}
counter = 0;
}
Gives me nullreference exception on File, not sure what my conclusion should be from this error. Admitting that I am pretty tired atm , probably going to realize exactly what it was on the way home :)
FINAL EDIT:
See answers my own post.
This code works fine. I had to be fired for not fixing this almost...... trying to assign values to uninitialized arrays and ignoring any mutable size....... Never happened!
foreach (string fileName in Directory.GetFiles(targetPath))
{
fileNameList_Original.Add(fileName);
foreach (string text in File.ReadAllLines(fileName))
{
fullFileText_Original.Add(text);
//fileNameList_Original[counter]
}
}
Thanks for spotting the fileName instead of targetPath SGB! That was also a mistake I made!
I fixed the rest of the problems on my own now.

Categories