I want to Load Directory Structure Into TreeView. If there is a txt file in folder it must be break. Child folders and files should not shown. Please help me to find an algorithm
private void ListDirectory(TreeView treeView, string path)
{
treeView.Nodes.Clear();
var rootDirectoryInfo = new DirectoryInfo(path);
treeView.Nodes.Add(CreateDirectoryNode(rootDirectoryInfo));
}
private static TreeNode CreateDirectoryNode(DirectoryInfo directoryInfo)
{
var directoryNode = new TreeNode(directoryInfo.Name);
foreach (var directory in directoryInfo.GetDirectories())
{
if (directory.Name.EndsWith("txt"))
{
break;
}
else
{
directoryNode.Nodes.Add(CreateDirectoryNode(directory));
}
}
foreach (var file in directoryInfo.GetFiles())
{
if (directoryNode.Name.EndsWith("txt"))
{
directoryNode.Nodes.Add(new TreeNode(file.Name));
}
}
return directoryNode;
}
I solved it like that,
private static TreeNode CreateDirectoryNode(DirectoryInfo directoryInfo)
{
var directoryNode = new TreeNode(directoryInfo.Name);
try
{
int flag = 0;
foreach (var file in directoryInfo.GetFiles())
{
if (file.Name.EndsWith("txt"))
{
flag = 1;
}
}
if (flag == 0)
{
foreach (var directory in directoryInfo.GetDirectories())
{
directoryNode.Nodes.Add(CreateDirectoryNode(directory));
}
}
return directoryNode;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return null;
}
}
Related
The code below returns only the most recent value in the loop. What do I need to do for it to show all the values that are being iterated over? The reason I am using this method instead of SearchOption.AllDirectory is because there is a folder path I am not able to access. I did try using UnauthorizedAccessException with a try and catch, but that returns an empty value because it keeps on terminating the loop.
public void Main()
{
string path = #"drive"; // TODO
ApplyAllFiles(path, ProcessFile);
}
public void ProcessFile(string path)
{
/* ... */
}
public void ApplyAllFiles(string folder, Action<string> fileAction)
{
System.Collections.ArrayList FileList = new System.Collections.ArrayList();
List<string> logger = new List<string>();
DateTime DateFilter = DateTime.Now.AddMonths(-6);
foreach (string file in Directory.GetDirectories(folder))
{
fileAction(file);
}
foreach (string subDir in Directory.GetDirectories(folder))
{
string rootfolder = "root folder";
if (subDir.Contains(rootfolder))
{
FileList.Add(subDir);
Dts.Variables["User::objDirectoryList"].Value = FileList;
//MessageBox.Show(subDir);
}
try
{
ApplyAllFiles(subDir, fileAction);
}
catch (UnauthorizedAccessException e)
{
logger.Add(e.Message);
}
catch (System.IO.DirectoryNotFoundException e)
{
logger.Add(e.Message);
}
}
}
Try to remove the FileList declaration outside the function, also remove Dts.Variables["User::objDirectoryList"].Value = FileList; outside the loop:
System.Collections.ArrayList FileList = new System.Collections.ArrayList();
public void Main()
{
string path = #"drive"; // TODO
ApplyAllFiles(path, ProcessFile);
Dts.Variables["User::objDirectoryList"].Value = FileList;
}
public void ProcessFile(string path)
{
/* ... */
}
public void ApplyAllFiles(string folder, Action<string> fileAction)
{
List<string> logger = new List<string>();
DateTime DateFilter = DateTime.Now.AddMonths(-6);
foreach (string file in Directory.GetDirectories(folder))
{
fileAction(file);
}
foreach (string subDir in Directory.GetDirectories(folder))
{
string rootfolder = "root folder";
if (subDir.Contains(rootfolder))
{
FileList.Add(subDir);
//MessageBox.Show(subDir);
}
try
{
ApplyAllFiles(subDir, fileAction);
}
catch (UnauthorizedAccessException e)
{
logger.Add(e.Message);
}
catch (System.IO.DirectoryNotFoundException e)
{
logger.Add(e.Message);
}
}
}
I've created a function used to populate a treeview with a targeted directory. However when I try to implement and error check to skip over folders which may have folder permission restrictions I get an error. Why do I get this error and how do i fix it?
Thank you in advance.
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace directoryBrowser
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
ListDirectory(treeView1, #"C:\Windows");
}
public void ListDirectory(TreeView treeView, string path)
{
treeView.Nodes.Clear();
var rootDirectoryInfo = new DirectoryInfo(path);
treeView.Nodes.Add(CreateDirectoryNode(rootDirectoryInfo));
}
public static TreeNode CreateDirectoryNode(DirectoryInfo directoryInfo)
{
//try
//{
var directoryNode = new TreeNode(directoryInfo.Name);
foreach (var directory in directoryInfo.GetDirectories())
{
directoryNode.Nodes.Add(CreateDirectoryNode(directory));
}
foreach (var file in directoryInfo.GetFiles())
{
directoryNode.Nodes.Add(new TreeNode(file.Name));
}
return directoryNode;
//}
//catch (UnauthorizedAccessException) { }
}
}
}
You are answering your own question. You get an error because the user account which this function is running under doesn't have permission to access some of the folder.
You should then apply a try/catch statement WITHIN the for loop so if you get this exception, you function will keep on running for following folders.
public static TreeNode CreateDirectoryNode(DirectoryInfo directoryInfo)
{
var directoryNode = new TreeNode(directoryInfo.Name);
foreach (var directory in directoryInfo.GetDirectories())
{
//try
{
directoryNode.Nodes.Add(CreateDirectoryNode(directory));
} catch {
// cannot access directory
}
}
foreach (var file in directoryInfo.GetFiles())
{
directoryNode.Nodes.Add(new TreeNode(file.Name));
}
return directoryNode;
}
Summary Of Problem:
I have a console app that, after copying many folders and files over to a new location, a local drive, it then deletes certain files/folders. One of these filetypes it deletes is .exe files. When trying to delete said files it gives me a denied access error.(This also occurs while trying to delete other kinds of files and folders as well)
Other Notes:
I saw several questions, such as Unable to delete .exe file through c#. However the process was never running on my local machine nor on the source it was copied from. I am both a local administrator and a domain administrator on our domain, and I had ownership over all folders and files in the directories I'm working with. But it still denies me access when trying to delete the file from code. I am however able to delete such files/folders manually.(click delete key)
Problem:
As stated above I am looking for a way to get past this issue denying me access to delete these "Illegal" file types and delete them from my code.
My Code:(Updated)
#region Delete_Illegal_Items
public static void RemoveIllegalItems()
{
Console.Clear();
DirectoryInfo Libraries = new DirectoryInfo(Library.DestinationMain);
try
{
foreach (var Lib in Libraries.GetDirectories())
{
Console.WriteLine("Working On {0}.", Lib.Name);
Parallel.Invoke(
() =>
{
RemoveBadFiles(Lib);
},
() =>
{
DeleteEmptyFolders(Lib);
}
);
}
}
catch (AggregateException e)
{
Console.WriteLine("There Was An Unusual Error During Initialization Of Library Correction:\n{0}", e.InnerException.ToString());
}
}
private static string[] BadFiles = {
#".hta",
#".exe",
#".lnk",
#".tmp",
#".config",
#".ashx",
#".hta.",
#".hta::$DATA",
#".zip",
#".asmx",
#".json",
#".soap",
#".svc",
#".xamlx",
#".msi",
#".ops",
#".pif",
#".shtm",
#".shtml",
#"smt",
#".vb",
#".vbe",
#".vbs",
#".ds_store",
#".db",
#".ini",
#".tiff"
};
private static void RemoveBadFiles(DirectoryInfo directory)
{
DirectoryInfo[] dirs = null;
FileInfo[] files = null;
if (directory != null)
{
files = directory.GetFiles();
}
try
{
dirs = directory.GetDirectories();
}
catch (IOException) { }
catch (Exception e)
{
Console.WriteLine("\nError During Enumeration Of Items To Delete:\n{0}", e.Message);
}
if (files != null)
{
foreach (var file in files)
{
try
{
if (file.IsReadOnly)
{
file.IsReadOnly = false;
}
if (BadFiles.Contains(Path.GetExtension(file.FullName)))
{
File.Delete(file.FullName);
}
}
catch (Exception e)
{
Console.WriteLine("\nError During Removal Or Illegal Files:\n" + e.Message);
}
}
}
if (dirs != null)
{
foreach (var dir in dirs)
{
switch (dir.Name)
{
case ".TemporaryItems":
{
try
{
Directory.Delete(dir.FullName);
}
catch { }
break;
}
case "AI_RecycleBin":
{
try
{
Directory.Delete(dir.FullName);
}
catch { }
break;
}
case ".ToRemove":
{
try
{
Directory.Delete(dir.FullName);
}
catch { }
break;
}
default:
{
break;
}
}
RemoveBadFiles(dir);
}
}
}
private static void DeleteEmptyFolders(DirectoryInfo directory)
{
Program Main = new Program();
try
{
DirectoryInfo[] dirs = directory.GetDirectories();
foreach (var subDirectory in dirs)
{
int sum = Library.CountLibrary(subDirectory.FullName);
if (sum == 0)
{
Directory.Delete(subDirectory.FullName);
}
DeleteEmptyFolders(subDirectory);
}
}
catch { }
}
#endregion
Any help would be greatly appreciated. If this question has been directly answered elsewhere please feel free to mention it in the comment. As I stated above I have been looking through past question regarding this issue and have not found a solution as of yet. Otherwise thank you for your help.
Figured out the problem was with the files being marked as "Read-only" so I added a if statement before the deletion of the file to check if it was and remove the mark if need be. Here is the code that worked successfully for deleting all the wanted files.
#region Delete_Illegal_Items
public static void RemoveIllegalItems()
{
Console.Clear();
DirectoryInfo Libraries = new DirectoryInfo(Library.DestinationMain);
try
{
foreach (var Lib in Libraries.GetDirectories())
{
Console.WriteLine("Working On {0}.", Lib.Name);
Parallel.Invoke(
() =>
{
RemoveBadFiles(Lib);
},
() =>
{
DeleteEmptyFolders(Lib);
}
);
}
}
catch (AggregateException e)
{
Console.WriteLine("There Was An Unusual Error During Initialization Of Library Correction:\n{0}", e.InnerException.ToString());
}
}
private static string[] BadFiles = {
#".hta",
#".exe",
#".lnk",
#".tmp",
#".config",
#".ashx",
#".hta.",
#".hta::$DATA",
#".zip",
#".asmx",
#".json",
#".soap",
#".svc",
#".xamlx",
#".msi",
#".ops",
#".pif",
#".shtm",
#".shtml",
#"smt",
#".vb",
#".vbe",
#".vbs",
#".ds_store",
#"ds_store",
#"._.Trashes",
#".Trashes",
#".db",
#".dat",
#".sxw",
#".ini",
#".tif",
#".tiff"
};
private static void RemoveBadFiles(DirectoryInfo directory)
{
DirectoryInfo[] dirs = null;
FileInfo[] files = null;
if (directory != null)
{
try
{
files = directory.GetFiles();
}
catch (IOException) { }
}
try
{
dirs = directory.GetDirectories();
}
catch (IOException) { }
catch (Exception e)
{
Console.WriteLine("\nError During Enumeration Of Items To Delete:\n{0}", e.Message);
}
if (files != null)
{
foreach (var file in files)
{
try
{
if (file.IsReadOnly)
{
file.IsReadOnly = false;
}
if (BadFiles.Contains(Path.GetExtension(file.FullName)) || BadFiles.Contains(file.Name))
{
File.Delete(file.FullName);
}
}
catch (Exception e)
{
Console.WriteLine("\nError During Removal Or Illegal Files:\n" + e.Message);
}
}
}
if (dirs != null)
{
foreach (var dir in dirs)
{
switch (dir.Name)
{
case ".TemporaryItems":
{
try
{
Directory.Delete(dir.FullName);
}
catch { }
break;
}
case "TemporaryItems":
{
try
{
Directory.Delete(dir.FullName);
}
catch { }
break;
}
case "AI_RecycleBin":
{
try
{
Directory.Delete(dir.FullName);
}
catch { }
break;
}
case ".ToRemove":
{
try
{
Directory.Delete(dir.FullName);
}
catch { }
break;
}
default:
{
break;
}
}
RemoveBadFiles(dir);
}
}
}
private static void DeleteEmptyFolders(DirectoryInfo directory)
{
Program Main = new Program();
try
{
DirectoryInfo[] dirs = directory.GetDirectories();
foreach (var subDirectory in dirs)
{
int sum = Library.CountLibrary(subDirectory.FullName);
if (sum == 0)
{
Directory.Delete(subDirectory.FullName);
}
DeleteEmptyFolders(subDirectory);
}
}
catch { }
}
#endregion
Thank you to those that comment and helped. And hope this can help others in the future.
I am creating an application which finds duplication in files. When I search files like:
try
{
string[] allFiles = Directory.GetFiles(
directoryPath, "*.*", SearchOption.AllDirectories
);
for (int i = 0; i < allFiles.Length; i++)
{
//decisions
}
}
catch (UnauthorizedAccessException ex)
{
MessageBox.Show(ex.Message);
}
it says
Access to path 'C:\$Recycle.Bin....... ' is denied.
I want if a folder is not accessible then move to the next but execution of program stops at Directory.GetFiles method.
Here's a class that will work:
public static class FileDirectorySearcher
{
public static IEnumerable<string> Search(string searchPath, string searchPattern)
{
IEnumerable<string> files = GetFileSystemEntries(searchPath, searchPattern);
foreach (string file in files)
{
yield return file;
}
IEnumerable<string> directories = GetDirectories(searchPath);
foreach (string directory in directories)
{
files = Search(directory, searchPattern);
foreach (string file in files)
{
yield return file;
}
}
}
private static IEnumerable<string> GetDirectories(string directory)
{
IEnumerable<string> subDirectories = null;
try
{
subDirectories = Directory.EnumerateDirectories(directory, "*.*", SearchOption.TopDirectoryOnly);
}
catch (UnauthorizedAccessException)
{
}
if (subDirectories != null)
{
foreach (string subDirectory in subDirectories)
{
yield return subDirectory;
}
}
}
private static IEnumerable<string> GetFileSystemEntries(string directory, string searchPattern)
{
IEnumerable<string> files = null;
try
{
files = Directory.EnumerateFileSystemEntries(directory, searchPattern, SearchOption.TopDirectoryOnly);
}
catch (UnauthorizedAccessException)
{
}
if (files != null)
{
foreach (string file in files)
{
yield return file;
}
}
}
}
You can the use it like this:
IEnumerable<string> filesOrDirectories = FileDirectorySearcher.Search(#"C:\", "*.txt");
foreach (string fileOrDirectory in filesOrDirectories)
{
// Do something here.
}
It's recursive, but the use of yield gives it a low memory footprint (under 10KB in my testing). If you want only files that match the pattern and not directories as well just replace EnumerateFileSystemEntries with EnumerateFiles.
I need to copy a whole directory C:\X to C:\Y\X, and I need the sub-folders to be copied as well.
Is there any way to do it with the System.IO.File\Directory namespaces ?
Thanks for all helpers!
This class will copy or move a folder, without recursive calls.
The methods is using their own stacks to handle recursion, this is to avoid StackOverflowException.
public static class CopyFolder
{
public static void CopyDirectory(string source, string target)
{
var stack = new Stack<Folders>();
stack.Push(new Folders(source, target));
while (stack.Count > 0)
{
var folders = stack.Pop();
Directory.CreateDirectory(folders.Target);
foreach (var file in Directory.GetFiles(folders.Source, "*.*"))
{
string targetFile = Path.Combine(folders.Target, Path.GetFileName(file));
if (File.Exists(targetFile)) File.Delete(targetFile);
File.Copy(file, targetFile);
}
foreach (var folder in Directory.GetDirectories(folders.Source))
{
stack.Push(new Folders(folder, Path.Combine(folders.Target, Path.GetFileName(folder))));
}
}
}
public static void MoveDirectory(string source, string target)
{
var stack = new Stack<Folders>();
stack.Push(new Folders(source, target));
while (stack.Count > 0)
{
var folders = stack.Pop();
Directory.CreateDirectory(folders.Target);
foreach (var file in Directory.GetFiles(folders.Source, "*.*"))
{
string targetFile = Path.Combine(folders.Target, Path.GetFileName(file));
if (File.Exists(targetFile)) File.Delete(targetFile);
File.Move(file, targetFile);
}
foreach (var folder in Directory.GetDirectories(folders.Source))
{
stack.Push(new Folders(folder, Path.Combine(folders.Target, Path.GetFileName(folder))));
}
}
Directory.Delete(source, true);
}
public class Folders
{
public string Source { get; private set; }
public string Target { get; private set; }
public Folders(string source, string target)
{
Source = source;
Target = target;
}
}
}
This is copied from xneurons blog.
public static void CopyAll(DirectoryInfo source, DirectoryInfo target) {
// Check if the target directory exists, if not, create it.
if (Directory.Exists(target.FullName) == false) {
Directory.CreateDirectory(target.FullName);
}
// Copy each file into it’s new directory.
foreach (FileInfo fi in source.GetFiles()) {
Console.WriteLine(#"Copying {0}\{1}", target.FullName, fi.Name);
fi.CopyTo(Path.Combine(target.ToString(), fi.Name), true);
}
// Copy each subdirectory using recursion.
foreach (DirectoryInfo diSourceSubDir in source.GetDirectories()) {
DirectoryInfo nextTargetSubDir =
target.CreateSubdirectory(diSourceSubDir.Name);
CopyAll(diSourceSubDir, nextTargetSubDir);
}
}
You can use SearchOption.AllDirectories to recursively search down folders, you just need to create the directories before you copy...
// string source, destination; - folder paths
int pathLen = source.Length;
foreach (string dirPath in Directory.GetDirectories(source, "*", SearchOption.AllDirectories))
{
string subPath = dirPath.SubString(pathLen);
string newpath = Path.Combine(destination, subPath);
Directory.CreateDirectory(newpath );
}
foreach (string filePath in Directory.GetFiles(source, "*.*", SearchOption.AllDirectories))
{
string subPath = filePath.SubString(pathLen);
string newpath = Path.Combine(destination, subPath);
File.Copy(filePath, newpath);
}