I am trying to access the Documents directory and sub-directories, but every time it says access denied. I see the Exception:
System.UnauthorizedAccessException: Access to the path 'C:\Users\MyUser\Documents\My Music' is denied
Here is my code - all I am trying to do is get the total size of this directory.
class Program
{
static void Main(string[] args)
{
try {
// Make a reference to a directory.
string path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
DirectoryInfo di = new DirectoryInfo(path);
// Get a reference to each file in that directory.
FileInfo[] fiArr = di.GetFiles(".", SearchOption.AllDirectories);
// Display the names and sizes of the files.
Console.WriteLine("The directory {0} contains the following files:", di.Name);
long size = 0;
foreach (FileInfo f in fiArr)
{
size += f.Length;
size++;
}
Console.WriteLine("The size of desktop files." + size);
}
catch(Exception e)
{
Console.WriteLine("Exceptions {0}" , e);
}
}
}
From what I can gather from skimming this thread it could be that these folders are soft links provided for Windows backward compatibility.
For resolving the coding problem, you could make your own recursive folder search that ignores the exceptions thrown when the current user does not have access to a given folder.
Something like this perhaps:
static IEnumerable<FileInfo> GetAllFilesRecursive(string path)
{
var di = new DirectoryInfo(path);
var files = new List<FileInfo>();
files.AddRange(di.GetFiles("."));
foreach (var directory in Directory.GetDirectories(path))
{
try
{
files.AddRange(GetAllFilesRecursive(directory));
}
catch (UnauthorizedAccessException) // ignore directories which the user does not have access to
{}
}
return files;
}
Then rewrite your code to use the new function:
static void Main(string[] args)
{
try
{
// Make a reference to a directory.
string path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
var fiArr = GetAllFilesRecursive(path);
// Display the names and sizes of the files.
Console.WriteLine("The directory {0} contains the following files:", path);
long size = 0;
foreach (FileInfo f in fiArr)
{
size += f.Length;
size++;
}
Console.WriteLine("The size of desktop files." + size);
}
catch (Exception e)
{
Console.WriteLine("Exceptions {0}", e);
}
}
The search should be on TopDirectoryOnly and not on AllDirectories.
The problem is in this line:
FileInfo[] fiArr = di.GetFiles(".", SearchOption.AllDirectories);
Change it to:
FileInfo[] fiArr = di.GetFiles(".", SearchOption.TopDirectoryOnly);
This should work.
Some SpecialFolders needs specific Admin priviledges to run without any exception. You must run your code in Admin priviledges.
Related
One Question about coding (Visual Studio C# Windows form Application) There have Two folder: (Source and Target) and I build 1 button "Copy". In (Source) folder have random folders such "20190401", "20190402", "20190403", "20180401", "20170401" and "20160401". Every these folders have [10] ".txt" files. What is the coding if I only want to copy all "201904**" folders with [3] ".txt" files inside to "Target" folder?
Here my code for now, after I click a button the folder wouldn't copy. I guess there have some problem with this codes and I still not found it until. Hope you guys can help me, thank you.
*namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
string FROM_DIR = "C:/Users/Desktop/Source/";
string TO_DIR = "C:/Users/Desktop/Target/";
DirectoryInfo diCopyForm = new DirectoryInfo(FROM_DIR);
DirectoryInfo[] fiDiskfiles = diCopyForm.GetDirectories();
string directname = "201904";
string filename = ".txt";
foreach (DirectoryInfo newfile in fiDiskfiles)
{
try
{
if (newfile.Name == "2019")
{
foreach (DirectoryInfo direc in newfile.GetDirectories())
if (direc.Name.StartsWith(directname))
{
int count = 0;
foreach (FileInfo file in direc.GetFiles())
{
if (file.Name.EndsWith(filename))
{
count++;
}
}
if (count == 3)
{
DirectoryCopy(direc.FullName,Path.Combine(TO_DIR,direc.Name), true);
count = 0;
MessageBox.Show("success");
}
}
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
}
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
// Get the subdirectories for the specified directory.
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
if (!dir.Exists)
{
throw new DirectoryNotFoundException("Source directory does not exist or could not be found: "+ sourceDirName);
}
DirectoryInfo[] dirs = dir.GetDirectories();
// If the destination directory doesn't exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
// Get the files in the directory and copy them to the new location.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
string temppath = Path.Combine(destDirName, file.Name);
file.CopyTo(temppath, false);
}
// If copying subdirectories, copy them and their contents to new location.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
string temppath = Path.Combine(destDirName, subdir.Name);
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
}
}
}
*}
By clicking the button, automatically copy all "201904**" folder and 3 ".txt files in (Source) folder to (target folder).
You didn't say which 3 txt files you want to copy so the code below copies all txt files, please explain how you select the files and I'll edit the code.
const string Source = #"C:\Users\Desktop\Source\";
const string Target = #"C:\Users\Desktop\Target\";
const string StartsWith = "201904";
const string FileType = "txt";
public static void Copy()
{
if (!Directory.Exists(Source)) //Check if the source directory exists
throw new Exception("Source directory is missing!");
Directory.CreateDirectory(Target); //If the target directory doesn't exists it will create one
var Directories = Directory.GetDirectories(Source, $"{StartsWith}*"); //Get directories which match the search pattern
for (int i = 0; i < Directories.Length; i++)
{
DirectoryInfo directory = new DirectoryInfo(Directories[i]);
Directory.CreateDirectory($"{Target}{directory.Name}"); //Create the directory in the target folder
var Files = Directory.GetFiles($"{Source}{directory.Name}", $"*.{FileType}"); //Get files
for (int j = 0; j < Files.Length; j++)
{
FileInfo file = new FileInfo(Files[j]);
File.Copy($"{Source}{directory.Name}" + #"\" + file.Name, $"{Target}{directory.Name}" + #"\" + file.Name); //Copy the file to the target folder
}
}
}
This code selects all directories which start with "201904" and all txt files inside them and copies it to the target folder.
EDIT: Fixed a mistake in the code
im doing something similar to the cmd tree. And what im planning to check first C:\ than check the first folder in it if the first folder contains something in it go check it and so on until i get DirectoryNotFoundException. If i get such i want to skip the first folder and check the second one how to do that ?
static string path = #"C:\";
static void Main()
{
try
{
DirectoryInfo di = new DirectoryInfo(path);
DirectoryInfo[] fileNames = di.GetDirectories();
}
catch (DirectoryNotFoundException)
{
DirectoryInfo di = new DirectoryInfo(path);
DirectoryInfo[] fileNames = di.GetDirectories();
//i need to edit the picking of filenames.Something like PickSecond/Next
}
Console.ReadKey();
}
If you want to print the directory tree you can use recursion without getting any DirectoryNotFoundException. The following code will print to the console all the sub-directories starting from a specific path. The recursion works this way: every time a folder is found, if it's not empty then go to explore its sub-directories, otherwise go and check the next folder.
static void DirectoryTree(string directory, string indent = "")
{
try
{
DirectoryInfo currentDirectory = new DirectoryInfo(directory);
DirectoryInfo[] subDirectories = currentDirectory.GetDirectories();
// Print all the sub-directories in a recursive way.
for (int n = 0; n < subDirectories.Length; ++n)
{
// The last sub-directory is drawn differently.
if (n == subDirectories.Length - 1)
{
Console.WriteLine(indent + "└───" + subDirectories[n].Name);
DirectoryTree(subDirectories[n].FullName, indent + " ");
}
else
{
Console.WriteLine(indent + "├───" + subDirectories[n].Name);
DirectoryTree(subDirectories[n].FullName, indent + "│ ");
}
}
}
catch (Exception e)
{
// Here you could probably get an "Access Denied" exception,
// that's very likely if you are exploring the C:\ folder.
Console.WriteLine(e.Message);
}
}
static void Main()
{
// Consider exploring a more specific folder. If you just type "C:\"
// you are requesting to view all the folders in your computer.
var path = #"C:\SomeFolder" ;
Console.WriteLine(path);
if(Directory.Exists(path))
DirectoryTree(path);
else
Console.WriteLine("Invalid Directory");
Console.ReadKey();
}
sdel = Server.MapPath("~/Media_Extracted_Content" + "/" + sfolder);
Directory.Delete(sdel,true);
'sfolder' contains different sub folder and all sub folder have contains different items. All items like image file, audio file, video file opened in browser .I am copying that items from this existing location to new location and after that I have to delete this directory from my system. Whenever I am trying to to this it shows error that Directory is not empty. Also, when I am trying to delete individual items from sub folder it is showing error that this file is being used by another process. Please help me.
I think at Server or at Hosting you have not given the permision to the folder which are, allow READ and WRITE to the Folder.
Please Try This Two FUNCTION/Method.
You only have to do is paste both function in class file(eg class1.cs).
In (aspx.cs)Assign Value to source and destination
For Example source = Server.MapPath("~/Media_Extracted_Content/" + sourcefolder);
destination = Server.MapPath("~/Media_Extracted_Content/" + destinationfolder);
And Call classobject.MoveFiles(source, destination,true);
public void createfolder(string directorypath)
{
// CREATE folder
try
{
Directory.CreateDirectory(directorypath);
}
catch (Exception ex)
{ }
}
public void MoveFiles(string source, string destination, bool overwrite)
{
System.IO.DirectoryInfo inputDir = new System.IO.DirectoryInfo(source);
System.IO.DirectoryInfo outputDir = new System.IO.DirectoryInfo(destination);
try
{
if ((inputDir.Exists))
{
if (!(outputDir.Exists))
{
createfolder(destination);
// outputDir.Create();
}
//Get Each files and copy
System.IO.FileInfo file = null;
foreach (System.IO.FileInfo eachfile in inputDir.GetFiles())
{
file = eachfile;
if ((overwrite))
{
file.CopyTo(System.IO.Path.Combine(outputDir.FullName, file.Name), true);
}
else
{
if (((System.IO.File.Exists(System.IO.Path.Combine(outputDir.FullName, file.Name))) == false))
{
file.CopyTo(System.IO.Path.Combine(outputDir.FullName, file.Name), false);
}
}
System.IO.File.Delete(file.FullName);
}
//Sub folder access code
System.IO.DirectoryInfo dir = null;
foreach (System.IO.DirectoryInfo subfolderFile in inputDir.GetDirectories())
{
dir = subfolderFile;
//Destination path
if ((dir.FullName != outputDir.ToString()))
{
MoveFiles(dir.FullName, System.IO.Path.Combine(outputDir.FullName, dir.Name), overwrite);
}
System.IO.Directory.Delete(dir.FullName);
}
}
}
catch (Exception ex)
{
}
}
Taken from: http://msdn.microsoft.com/en-us/library/dd383571.aspx
I've modified it to copy files, but even when I had it exactly as microsofts example, it still is ignoring the text file I placed in a subdirectory as a test...I'm dying to know what is going on here since I thought "SearchOption.AllDirectories" took care of that...
{
string sourceDirectory = #"C:\Users\root\Desktop\bms 2013\bms 2013";
string archiveDirectory = #"C:\Users\root\Desktop\test";
try
{
var txtFiles = Directory.EnumerateFiles(sourceDirectory, "*.txt", SearchOption.AllDirectories);
foreach (string currentFile in txtFiles)
{
string fileName = currentFile.Substring(sourceDirectory.Length + 1);
File.Copy(currentFile, Path.Combine(archiveDirectory, fileName));
}
}
catch (Exception)
{
// Console.WriteLine(e.Message);
}
}
I write this code and work when I select any folder (with search option = SearchOption.AllDirectories ) but for
Drive Like D:\ I get error
" access to path D:\System Volume Information is denied"
and I add "\" to this path but still get error
if (dirListBox.Items.Count == 0)
{
foreach (int Index in disksListBox.CheckedIndices)
{
String Dir = disksListBox.Items[Index].ToString().Substring(0, 2);
Dir += #"\";
if (CheckExists(Dir))
{
Dirs.Add(Dir);
}
}
}
else
{
for (int Index = 0; Index < dirListBox.Items.Count; Index++)
{
String Dir = dirListBox.Items[Index].ToString();
Dirs.Add(Dir);
}
}
if (rdb_thisdir.Checked == true)
OptionDir = SearchOption.TopDirectoryOnly;
else
OptionDir = SearchOption.AllDirectories; // when search D:\ , Get Error But Work for Folder
if (rdbversion1.Checked == true)
{
ListViewItem lstitm = new ListViewItem();
foreach (String Dir in Dirs)
{
try
{
DirectoryInfo DirInfo = new DirectoryInfo(Dir);
FileInfo[] FileS = DirInfo.GetFiles(SearchPattern,OptionDir); //error when Dir="D:\\"
foreach (FileInfo file in FileS)
{
try
{
if (Check_Attributes(file) && Check_DateTime(file))
{
listFileFounded.Items.Add(file.FullName.ToString());
lstitm = lwfound.Items.Add(file.Extension.ToString());
lstitm.SubItems.Add(file.Name.ToString());
lstitm.SubItems.Add((file.Length / 1024).ToString());
lstitm.SubItems.Add(file.Attributes.ToString());
lstitm.SubItems.Add(file.FullName.ToString());
}
}
catch
{ }
}
}
catch ()
{
}
}
Your D: drive contains a folder "System Volume Information" that you don't have the privileges to access. So you will need to either not access it, or catch the exception and handle it to your liking. Not having access to a folder is not uncommon outside of ones own PC, so you might want to think about handling that scenario in your user interface. Maybe paint the folder in grey or display a lock icon or something.
There was a trick to do it. Do Enable Sharing to this folder.
For more information id here
Or do this trick .....
static void RecursiveGetFiles(string path)
{
DirectoryInfo dir = new DirectoryInfo(path);
try
{
foreach (FileInfo file in dir.GetFiles())
{
MessageBox.Show(file.FullName);
}
}
catch (UnauthorizedAccessException)
{
Console.WriteLine("Access denied to folder: " + path);
}
foreach (DirectoryInfo lowerDir in dir.GetDirectories())
{
try
{
RecursiveGetFiles(lowerDir.FullName);
}
catch (UnauthorizedAccessException)
{
MessageBox.Show("Access denied to folder: " + path);
}
}
}
}
kamil Krasinsky answered it .. here