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?
Related
I have below code to retrieve all pdf files from MyComputer. But i am getting error like below. Is it possible to retrive all pdf files from one computer using C# code.
string path = Environment.GetFolderPath(Environment.SpecialFolder.MyComputer);
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(path); // Error : The path is not of a legal form.
IEnumerable<System.IO.FileInfo> fileList = dir.GetFiles("*.pdf", System.IO.SearchOption.AllDirectories);
You can get all drives and then get all files.
EDIT: You can also use Directory.EnumerateFiles method which would let you get the file path and you can add that in your list. This would give you a List<string> for all the file paths. Like:
List<string> filePathList = new List<string>();
foreach (DriveInfo drive in DriveInfo.GetDrives())
{
try
{
var filenames = Directory.EnumerateFiles(drive.Name, "*.pdf", SearchOption.AllDirectories);
foreach (string fileName in filenames)
{
filePathList.Add(fileName);
}
}
catch (FieldAccessException ex)
{
//Log, handle Exception
}
catch (UnauthorizedAccessException ex)
{
//Log, handle Exception
}
catch (Exception ex)
{
//log , handle all other exceptions
}
}
Old Answer.
List<FileInfo> fileList = new List<FileInfo>();
foreach (var drive in System.IO.DriveInfo.GetDrives())
{
try
{
DirectoryInfo dirInfo = new DirectoryInfo(drive.Name);
foreach (var file in dirInfo.GetFiles("*.pdf", SearchOption.AllDirectories))
fileList.Add(file);
}
catch (FieldAccessException ex)
{
//Log, handle Exception
}
catch (UnauthorizedAccessException ex)
{
//Log, handle Exception
}
catch (Exception ex)
{
//log , handle all other exceptions
}
}
You can use the System.IO.DriveInfo class to loop through all drives available on the machine (call DriveInfo.GetDrives() to get a list of all drives). You will probably have to do this for each drive and combine the results from all of them. My guess with what is wrong with your current code is that giving it the MyComputer folder isn't enough to tell it to loop through all drives.
var path = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache);
var dInfo = new DirectoryInfo(path);
foreach (FileInfo f in dInfo.GetFiles())
{
Console.WriteLine(f.ToString());
}
This only prints out one file titled "desktop.ini". I know that Temporary Internet Files is a virtual folder. How can I iterate through files in a virtual folder?
What your accessing with your code is the top level folder. To iterate through all the files you will need to take into account all the sub folders in the Temporary Internet Files.
static void Main(string[] args)
{
var path = Environment.GetFolderPath(Environment.SpecialFolder.InternetCache);
var dInfo = new DirectoryInfo(path);
DoStuff(dInfo);
Console.ReadLine();
}
static void DoStuff(DirectoryInfo directory)
{
foreach (var file in directory.GetFiles())
{
Console.WriteLine(file.FullName);
}
foreach (var subDirectory in directory.GetDirectories())
{
DoStuff(subDirectory);
}
}
I have a folder that contains sub folders and files with read only attribute (both files and folders). I want to delete this folder with sub-folders and files.
I wrote this code:
static void Main(string[] args)
{
DirectoryInfo mm = new DirectoryInfo(#"c:\ex");
string aa = Convert.ToString(mm);
string[] allFileNames =
System.IO.Directory.GetFiles(aa,
"*.*",
System.IO.SearchOption.AllDirectories);
string[] alldirNames =
System.IO.Directory.GetDirectories(aa,
"*",
System.IO.SearchOption.AllDirectories);
foreach (string filename in allFileNames)
{
FileAttributes attr = File.GetAttributes(filename);
File.SetAttributes(filename, attr & ~FileAttributes.ReadOnly);
}
foreach (string dirname in alldirNames)
{
FileAttributes attr = File.GetAttributes(dirname);
File.SetAttributes(dirname, attr & ~FileAttributes.ReadOnly);
Directory.Delete(dirname , true);
}
FileInfo[] list = mm.GetFiles();
foreach (FileInfo k in list)
{
k.Delete();
}
mm.Delete();
Console.ReadKey();
}
The problem now is that whenever I run the program it gives me the following error:
Could not find a part of the path 'c:\ex\xx\bb'.
What does this error mean?
Directory.Delete(path, true);
Documentation
The previous answer might work, but I believe it will occur with problems in ReadOnly files. But to ensure the deletion and removal of any attribute ReadOnly, the best way to perform this procedure you must be using a method to facilitate the way you were doing, you were not using the correct properties of objects, for example, when using
DirectoryInfo.ToString ()
and use the
DirectoryInfo.GetFiles (aa ...
you were not using the resources the Framework offers within the DirectoryInfo class. See below:
void DirectoryDelete(string strOriginalPath)
{
DirectoryInfo diOriginalPath = new DirectoryInfo(strOriginalPath);
if (diOriginalPath.Attributes.HasFlag(FileAttributes.ReadOnly))
diOriginalPath.Attributes &= ~FileAttributes.ReadOnly;
string[] lstFileList = Directory.GetFiles(strOriginalPath);
string[] lstdirectoryList = Directory.GetDirectories(strOriginalPath);
if (lstdirectoryList.Length > 0)
{
// foreach on the subdirs to the call method recursively
foreach (string strSubDir in lstdirectoryList)
DirectoryDelete(strSubDir);
}
if (lstFileList.Length > 0)
{
// foreach in FileList to be delete files
foreach (FileInfo fiFileInDir in lstFileList.Select(strArquivo => new FileInfo(strArquivo)))
{
// removes the ReadOnly attribute
if (fiFileInDir.IsReadOnly)
fiFileInDir.Attributes &= ~FileAttributes.ReadOnly;
// Deleting file
fiFileInDir.Delete();
}
}
diOriginalPath.Delete();
}
EmptyFolder(new DirectoryInfo(#"C:\your Path"))
Directory.Delete(#"C:\your Path");
private void EmptyFolder(DirectoryInfo directoryInfo)
{
foreach (FileInfo file in directoryInfo.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo subfolder in directoryInfo.GetDirectories())
{
EmptyFolder(subfolder);
}
}
I am trying to retrieve all the files in all the folders I have in a directory .
But the result is quite random ..
I think the foreach is wrong ..
What I don't understand is why ?
Because in all the folders , we check all the files and then display a link buttons of all the files . But actually it's displaying a lot of folders , twice .
var DI = new DirectoryInfo("C://inetpub//wwwroot//ClientPortal//Files//")
.GetDirectories("*.*", System.IO.SearchOption.AllDirectories);
foreach (System.IO.DirectoryInfo D1 in DI)
{
System.IO.FileInfo[] fiArr = D1.GetFiles();
foreach (System.IO.FileInfo file in fiArr)
{
LinkButton lktest = new LinkButton();
lktest.Text = D1.Name;
form1.Controls.Add(lktest);
form1.Controls.Add(new LiteralControl("<br>"));
}
}
Can someone help me ?
Thanks a lot !
display a link buttons of all the files
Here you're creating link buttons with the name set to the directory when it sounds like you want the file instead (ie file.Name instead of D1.Name)
lktest.Text = D1.Name;
Does this help?
http://www.dreamincode.net/code/snippet1669.htm
public void GetDirStructure(string path)
{
try
{
DirectoryInfo dir = new DirectoryInfo(path);
DirectoryInfo[] subDirs = dir.GetDirectories();
FileInfo[] files = dir.GetFiles();
foreach(FileInfo fi in files)
{
Console.WriteLine(fi.FullName.ToString());
}
if (subDirs != null)
{
foreach (DirectoryInfo sd in subDirs)
{
GetDirStructure(path + #"\\" + sd.Name);
}
}
}
catch(Exception ex)
{
Console.WriteLine(ex.Message.ToString());
}
}
The first line of code seems like the culprit:
System.IO.DirectoryInfo[] DI = new System.IO.DirectoryInfo("C://inetpub//wwwroot//ClientPortal//Files//").GetDirectories("*.*", System.IO.SearchOption.AllDirectories);
Try using the following:
DirectoryInfo[] DI = new DirectoryInfo("C://inetpub//wwwroot//ClientPortal//File//").GetDirectories();
Well I like this nice piece of code right here it seems to work awesomely but I can't seem to add any more directories to it
DirectoryInfo dir = new DirectoryInfo(#"C:\temp");
foreach(FileInfo files in dir.GetFiles())
{
files.Delete();
}
foreach (DirectoryInfo dirs in dir.GetDirectories())
{
dirs.Delete(true);
}
I would also like to add in special folders as well like History and cookies and such how would I go about doing that (I would like to include at least 4-5 different folders)
Perhaps something like this would help. I did not test it.
public void DeleteDirectoryFolders(DirectoryInfo dirInfo){
foreach (DirectoryInfo dirs in dirInfo.GetDirectories())
{
dirs.Delete(true);
}
}
public void DeleteDirectoryFiles(DirectoryInfo dirInfo) {
foreach(FileInfo files in dirInfo.GetFiles())
{
files.Delete();
}
}
public void DeleteDirectoryFilesAndFolders(string dirName) {
DirectoryInfo dir = new DirectoryInfo(dirName);
DeleteDirectoryFiles(dir)
DeleteDirectoryFolders(dir)
}
public void main() {
List<string> DirectoriesToDelete;
DirectoriesToDelete.add("c:\temp");
DirectoriesToDelete.add("c:\temp1");
DirectoriesToDelete.add("c:\temp2");
DirectoriesToDelete.add("c:\temp3");
foreach (string dirName in DirectoriesToDelete) {
DeleteDirectoryFilesAndFolders(dirName);
}
}
Here's a recursive function that will delete all files in a given directory and navigate down the directory structure. A pattern string can be supplied to only work with files of a given extension, as per your comment to another answer.
Action<string,string> fileDeleter = null;
fileDeleter = (directoryPath, pattern) =>
{
string[] files;
if (!string.IsNullOrEmpty(pattern))
files = Directory.GetFiles(directoryPath, pattern);
else
files = Directory.GetFiles(directoryPath);
foreach (string file in files)
{
File.Delete(file);
}
string[] directories = Directory.GetDirectories(directoryPath);
foreach (string dir in directories)
fileDeleter(dir, pattern);
};
string path = #"C:\some_folder\";
fileDeleter(path, "*.bmp");
Directories are otherwise left alone, and this can obviously be used with an array or list of strings to work with multiple initial directory paths.
Here is the same code rewritten as a standard function, also with the recursion as a parameter option.
public void DeleteFilesFromDirectory(string directoryPath, string pattern, bool includeSubdirectories)
{
string[] files;
if (!string.IsNullOrEmpty(pattern))
files = Directory.GetFiles(directoryPath, pattern);
else
files = Directory.GetFiles(directoryPath);
foreach (string file in files)
{
File.Delete(file);
}
if (includeSubdirectories)
{
string[] directories = Directory.GetDirectories(directoryPath);
foreach (string dir in directories)
DeleteFilesFromDirectory(dir, pattern, includeSubdirectories);
}
}