I'm trying to list all folders and files in my User folder which is "Thomas", then I want to get all of the folders in those folders as well as files and so on. But whenever I run it, it throws this exception:
System.UnauthorizedAccessException: Access to the path 'C:\Users\Thomas\AppData\Local\Application Data' is denied.
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileSystemEnumerableIterator`1.AddSearchableDirsToStack(SearchData localSearchData)
at System.IO.FileSystemEnumerableIterator`1.MoveNext()
at System.Collections.Generic.List`1..ctor(IEnumerable`1 collection)
at System.IO.Directory.GetDirectories(String path, String searchPattern, SearchOption searchOption)
at GetFilesInFolders.Program.Main(String[] args) in c:\users\thomas\documents\visual studio 2017\Projects\GetFilesInFolders\GetFilesInFolders\Program.cs:line 23
I find this strange since I have FULL permission to access this folder, but for some reason it says other-wise.
All of the code is below:
using System;
using System.IO;
using System.Collections.Generic;
namespace GetFilesInFolders
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Enter a path: ");
string path = Console.ReadLine();
int UnauthorizedAccessCount = 0;//counter for file i cant access
List<string> DirList = new List<string>();
List<string> FileList = new List<string>();
try
{
if (Directory.Exists(path))
{
foreach (string dir in Directory.GetDirectories(path, "*", SearchOption.AllDirectories))
{
DirList.Add(dir);
}
foreach (string file in Directory.GetFiles(path, "*", SearchOption.AllDirectories))
{
FileList.Add(file);
}
}
else
{
Console.WriteLine("Directory does not exist!");
Console.ReadKey();
return;
}
}
catch (UnauthorizedAccessException ex)
{
Console.WriteLine("{0}", ex);
}
if(FileList.Count == 0)
{
Console.WriteLine("There were no files, or you didn't have proper permissions. (You didn't have permission to {0} files or folders", UnauthorizedAccessCount);
Console.ReadKey();
}
if(DirList.Count == 0)
{
Console.WriteLine("There were no folders, or you didn't have proper permissions. (You didn't have permission to {0} files or folders", UnauthorizedAccessCount);
Console.ReadLine();
}
else
{
Console.WriteLine("Here are all the folders:\n");
foreach (string dir in DirList)
{
Console.WriteLine(dir);
}
Console.WriteLine("Here are all the files:\n");
foreach (string file in FileList)
{
Console.WriteLine(file);
}
if (UnauthorizedAccessCount != 0)
{
Console.WriteLine("You had no permission to access {0} files.", UnauthorizedAccessCount);
}
else
{
}
Console.ReadLine();
}
}
}
}
You say you have full permission, but a console script does not run with the priviliges of the account. It runs with default user priviliges, and App Datais a restricted folder in Windows (where normal users are not supposed to poke around).
Change your console application to actually run as administrator. See this answer on how to do that:
How do I force my .NET application to run as administrator?
Related
I want to get the full path of the file named wampmanager.conf on disk D. I coded the following for this:
private static string Scan(string path, string file)
{
try
{
foreach (var dir in Directory.EnumerateDirectories(path))
{
foreach (var fl in Directory.EnumerateFiles(dir, file))
{
if (!string.IsNullOrEmpty(fl))
{
return fl;
}
}
}
}
catch (Exception)
{
// ignored
}
return null;
}
var wmc = Scan(#"D:\", "wampmanager.conf");
MessageBox.Show(wmc);
It always returns null even though the wampmanager.conf file exists on the disk D. I guess it goes to a directory like d:\recovery\ that I don't have access to, then it crashes into a catch and returns null. But when I don't use try catch I always get access authorization error. How can I deal with this problem?
For each directory you must use SearchOption.AllDirectories to Includes the current directory and all its subdirectories in a search operation. Try this function:
private static string Scan(string path, string file)
{
foreach (var dir in Directory.EnumerateDirectories(path))
try
{
string[] files = Directory.GetFiles(dir, file, SearchOption.AllDirectories);
if (files.Length > 0)
{
return files[0];
}
}
catch (Exception e)
{
string s = e.Message;
}
return "not found!";
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
namespace Application2
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Btn_search_Click(object sender, EventArgs e)
{
//Uses the text entered by user
//searchAndCopy(txtbox1.Text);
//Uses file for copy process
searchAllLines(#"D:\Icyer\liste2.txt");
}
private void searchAllLines(string filename)
{
foreach (string line in File.ReadLines(filename))
{
searchAndCopy(line);
}
}
private void searchAndCopy(string textToSearch)
{
// MessageBox.Show("|" + textToSearch + "|");
string srcfolder = #"X:\xxxx\xxxx\xxxx\xxxx";
DirectoryInfo Ordner = new DirectoryInfo(srcfolder);
FileInfo[] Pfad = Ordner.GetFiles("*" + textToSearch + "*", SearchOption.AllDirectories);
foreach (var item in Pfad)
{
string destinationDirectory = #"D:\xxxx\Copy\";
//Directory.CreateDirectory(destinationDirectory);
string[] substrings = item.FullName.Split('\\');
string folder = substrings[srcfolder.Split('\\').Length - 1];
if(folder == textToSearch) {
DirectoryCopy(srcfolder + folder, destinationDirectory + folder, true);
}
//File.Copy(item.FullName, item.Name);
}
}
private static void DirectoryCopy(string sourceDirName, string destDirName, bool copySubDirs)
{
DirectoryInfo dir = new DirectoryInfo(sourceDirName);
DirectoryInfo[] dirs = dir.GetDirectories();
// If the source directory does not exist, throw an exception.
if (!dir.Exists)
{
throw new DirectoryNotFoundException(
"Source directory does not exist or could not be found: " + sourceDirName);
}
// If the destination directory does not exist, create it.
if (!Directory.Exists(destDirName))
{
Directory.CreateDirectory(destDirName);
}
// Get the file contents of the directory to copy.
FileInfo[] files = dir.GetFiles();
foreach (FileInfo file in files)
{
// Create the path to the new copy of the file.
string temppath = Path.Combine(destDirName, file.Name);
try
{
// Copy the file.
file.CopyTo(temppath, false);
}
catch { };
}
// If copySubDirs is true, copy the subdirectories.
if (copySubDirs)
{
foreach (DirectoryInfo subdir in dirs)
{
// Create the subdirectory.
string temppath = Path.Combine(destDirName, subdir.Name);
// Copy the subdirectories.
DirectoryCopy(subdir.FullName, temppath, copySubDirs);
}
//MessageBox.Show("Done!");
}
}
}
}
The code works perfectly fine when I try to copy from "D: to D:", when I try to change the code from
string srcfolder = #"D:\xxxx\xxxx\";
to
string srcfolder = #"X:\xxxx\xxxx\xxxx\xxxx";
The application freezes the second I press on the button. Can someone tell me if it has to do because I'm trying to copy files from a server or is there an error in the code somewhere. Access to the server is granted and I have rights to copy files. Destination should stay on "D:". "X:" to "X:" doesnt work either, Application freezes the second the button is pressed.
As your comments indicate there are to many files in the directory and you are retrieving all and then iterating them again in your sub function. A local disk is always much faster than a network location - also perhaps you just have some test data in your local disk and not the whole tree mirrored.
In general you should offload your processing into a separate thread - this way you can pass back 'status information' to your gui thread and display them (the application will not stale anymore).
With this line:
FileInfo[] Pfad = Ordner.GetFiles("*" + textToSearch + "*", SearchOption.AllDirectories);
you retrieve all files which match your textSearch string in all sub directories. Depending on the number of files and directories this can take a very long time.
Perhaps it would be better to iterate each directory recursive checking the content if something does need to get copied?
About offloading to another thread you can take a look here
Basically I am trying to make a program that empties or even deletes a certain file, the thing is, this file is about 3 or 4 or so folders past the macromedia folder, and it can be it different named folders for anyone, so that is why the string[] files is done like that, it just checks for basically "FlashGame.sol" in EVERY folder after the macromedia folder.
I commented where I need help, I basically need to empty the contents of the file, or just flat out delete it.
private void button1_Click(object sender, EventArgs e)
{
string path = textBox1.Text + "/AppData/Roaming/Macromedia"; //the person using the program has to type in the beginning of the directory, C:/Users/Mike for example
bool Exists = Directory.Exists(path);
try
{
if (Exists)
{
string[] files = Directory.GetFiles(path, "*FlashGame.sol", SearchOption.AllDirectories);
string[] array = files;
for (int i = 0; i < array.Length; i++)
{
string info;
string text = array[i];
using (StreamReader streamReader = new StreamReader(text))
{
info = streamReader.ReadToEnd();
//erase the contents of the file here or even delete it
}
}
}
}
catch
{
MessageBox.Show("The given directory was not found", "Error", MessageBoxButtons.OK);
}
}
You can clear a file this way:
System.IO.File.WriteAllText(#"file.path",string.Empty);
So you should probably change your Code to:
string[] files = Directory.GetFiles(path, "*FlashGame.sol", SearchOption.AllDirectories);
foreach (var file in files)
{
System.IO.File.WriteAllText(file, string.Empty);
}
Also take a look at Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), which gives the appdata directory of the current user.
Also never catching a Exception without handling it correctly. You already know, if the directory exists via your Exists Variable.
string path = Environment.ExpandEnvironmentVariables(#"%AppData%\Macromedia\"); // Example C:\Users\Mike\AppData\Roaming\Macromedia\
if (Directory.Exists(path)) {
string[] files = Directory.EnumerateFiles(path, "*FlashGame.sol", SearchOption.AllDirectories);
foreach (string file in files) {
try {
File.Delete(file);
}
catch (Exception ex) {
MessageBox.Show(ex.Message);
}
}
}
I am trying to build a program will show all files and directories in a given directory , and the size of each item .
for the folders size I used https://stackoverflow.com/a/2981241/4645644 as it seems nice and understandable for me.
I noticed that when I try to use GetFiles() or GetDirecories() I get exception if there is none exist .
I tried to write to console when this happens but nothing is written to the console yet it doesnt do the try part and I don't understand what is happening or what I missed.
public static void Main(string[] args)
{
Console.WriteLine("write path folder");
string path = Console.ReadLine();
DirectoryInfo di = new DirectoryInfo(#path);
//int check=1;
bool iterating = true;
if (!Directory.Exists(path))
{
Console.WriteLine("{0} not found , path is wrong or there is no such directory", path);
}
else
{
while (iterating)
{
Console.WriteLine("Name,Root,Parent -> {0},{1},{2}", di.Name, di.Root, di.Parent);
Console.WriteLine("{0} full size is : {1}", di.Name, DirSize(di));
try
{
foreach (DirectoryInfo sfolder in di.GetDirectories())
{
Console.WriteLine("Folder Name: {0} , Folder size - {1} KB", sfolder.Name, DirSize(sfolder));
}
}
catch
{
Console.WriteLine("No subfolder in thie folder : {0}", di.FullName);
}
try
{
foreach (FileInfo sfile in di.GetFiles())
{
Console.WriteLine("File name : {0} , File size - {1} KB", sfile.Name, sfile.Length);
}
}
catch
{
Console.WriteLine("No files in thie folder : {0}", di.FullName);
}
iterating = false;
}
}
}
Add Console.ReadKey(); at the end of your Main method. So, application will not close after executing.
i want to write a program, which can copy all txt files on my local Pc to a specific location. This is no problem so far i have the rights to open the directory. Some directorys throw a UnauthorizedException. Is it possible to first get access and then read the files? This is what iam doing so far:
public List<FileInfo> SearchFiles(List<string> pattern)
{
List<FileInfo> files = new List<FileInfo>();
foreach (DriveInfo drive in DriveInfo.GetDrives())
{
var dirs = from dir in drive.RootDirectory.EnumerateDirectories()
select new
{
ProgDir = dir,
};
foreach (var di in dirs)
{
try
{
foreach (string muster in pattern)
{
foreach (var fi in di.ProgDir.EnumerateFiles(muster, SearchOption.AllDirectories))
{
try
{
files.Add(fi);
}
catch (UnauthorizedAccessException)
{
}
}
}
}
catch (UnauthorizedAccessException)
{
}
}
}
return files;
}
The List with strings give the pattern the method is searching for. For Example all txt files and all files with hallo in name or what ever.
You could try promoting the rights of the application when it runs.
How to request administrator permissions when the program starts?