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.
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!";
}
I created folder with no name using (alt + 0160) while I search with c# it stuck in infinite loop and create exception of "Stack Over Flow"
My method is given which i am using for Search.
public void getTotatFoldersAndFilesCount(DirectoryInfo objDirs, System.ComponentModel.BackgroundWorker worker)
{
try{
if (worker.CancellationPending == true)
{ return; }
FileInfo[] objFiles = null;
numFoldersCount++;
if ((objDirs.Attributes & FileAttributes.ReparsePoint) != 0)
{ return;}
try
{
objFiles = objDirs.GetFiles(searchPatteren);
}
catch (UnauthorizedAccessException e)
{ }
catch (System.IO.DirectoryNotFoundException e)
{ }
catch (System.StackOverflowException ex)
{ }
if (objFiles != null)
{
foreach (FileInfo objFile in objFiles)
{
numFilesCount++;
}
foreach (DirectoryInfo objDir in objDirs.GetDirectories())
{
getTotatFoldersAndFilesCount(objDir, worker);
}
}
objFiles = null;
}
catch (Exception ex)
{
ErrorLogger("Error in Total Folder and File Count - Directory Name: " + objDirs.Name);
ErrorLogger(ex.Message);
}
}
This can be avoided by a simple change:
In the directory enumeration code, change the for loop to:
foreach (DirectoryInfo objDir in new DirectoryInfo(objDirs.FullName + Path.DirectorySeparatorChar).GetDirectories(searchPatteren))
{
getTotatFoldersAndFilesCount(objDir, worker);
}
When enumerating blank folder, the directory name is a white space. When initializing the DirectoryInfo object, the whitespace is trimmed causing the function to always loop trough the same directory. Adding the DirectorySeperatorChar ("\") in most of the cases solves the issue.
I google this question and find the solution by given link.
by adding single slash at the end of the directory path it will not go into infinite loop.
first i was doing this.
getTotatFoldersAndFilesCount(objDir, worker);
and now replace it with this. It solved my problem,
DirectoryInfo nDI = new DirectoryInfo(objDir.FullName + #"\");
getTotatFoldersAndFilesCount(nDI, worker);
link is given.
http://tiku.io/questions/4277530/getdirectories-fails-to-enumerate-subfolders-of-a-folder-with-255-name
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?
String userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
String dr = #"C:\Users\" + userName + #"\AppData\temp";
DirectoryInfo dir = new DirectoryInfo(#dr);
foreach (FileInfo file in dir.GetFiles())
{
file.Delete();
}
foreach (DirectoryInfo dire in dir.GetDirectories())
{
dire.Delete(true);
}
i was using this for deleting contents of a folder and that should be depending upon the username of the computer & i have provided the admin privilege
but when any file doesnt delete it stops working at that file. i want this process to complete
String userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
String dr = #"C:\Users\" + userName + #"\AppData\temp";
DirectoryInfo dir = new DirectoryInfo(#dr);
foreach (FileInfo file in dir.GetFiles())
{
try
{
file.Delete();
}
catch (IOException ex)
{//Log ex.message
continue;
}
}
foreach (DirectoryInfo dire in dir.GetDirectories())
{
try
{
dire.Delete();
}
catch (IOException ex)
{ //Log ex.message
continue;
}
}
Moreover, I suggest you better use Path.Combine() instead of concatenating Strings.
You'll have to add try/catch blocks around the file deletion statement, so that your loops continue even if you get an exception. I would recommend logging the list of files which have thrown exceptions when you call delete.
If one of the files won't delete, the call to file.Delete() will throw an exception.
If you want to handle it, you must wrap it in a try/catch as follows:
foreach (FileInfo file in dir.GetFiles())
{
try
{
file.Delete();
}
catch (IOException exception)
{
// Here you should log the exception.Message
}
}
I am having a bit of trouble with this method.
When I loop through the FileInfo type objects in dragDropFiles and add each individually to the CLB I get the FullName property (full path to file, which is what I need) returned when the item is checked.
However with the hotFolderFiles instead of the path it gives me just the file name.
I do not understand this because they are adding the same object type in the same manner.
(I also tried getting the FileInfo for hot folder files using the DirectoryInfo instead of my Dictionary with same results)
Why is this behavior inconsistent?
(and how can I get it to return the fileInfo fullName instead of Name?)
public frmFilesFound(string hotFolderPath, Dictionary<string, FileInfo> dragDropFiles, Dictionary<string, FileInfo> hotFolderFiles, bool ReadOnly)
{
try
{
InitializeComponent();
readOnly = ReadOnly;
btnSelectAll.Visible = true;
clbSelectFilesFound.Visible = true;
clbSelectFilesFound.FormattingEnabled = true;
clbSelectFilesFound.Format += (s, e) => { e.Value = string.Format("{0}", ((FileInfo)e.ListItem).Name); };
foreach (FileInfo fileInfo in dragDropFiles.Values)
{
if (!clbSelectFilesFound.Items.Contains(fileInfo))
{
try
{
// If file not already present, add it to listbox
clbSelectFilesFound.Items.Add(fileInfo);
}
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); }
}
}
//intended to be hot folder path
if (!String.IsNullOrEmpty(hotFolderPath))
{
DirectoryInfo dirInfo = new DirectoryInfo(hotFolderPath);
foreach (FileInfo fileInfo in dirInfo.GetFiles())
//foreach (FileInfo fileInfo in hotFolderFiles.Values)
{
if (!clbSelectFilesFound.Items.Contains(fileInfo))
{
try
{
clbSelectFilesFound.Items.Add(fileInfo);
}
catch (Exception ex) { MessageBox.Show("Error: " + ex.Message); }
}
}
}
lblDisplayedSelectMessage.Text = "More than one file is waiting. Please select the files you would like to use.";
}
catch (Exception ex)
{ MessageBox.Show(ex.ToString()); }
}
That is because the DirectoryInfo.GetFiles method only fills in the name of the file, and not the full path.
Try this formatter if you only want to show the name of the file in all cases:
clbSelectFilesFound.Format += (s, e) => {
e.Value = Path.GetFileNameWithoutExtension(((FileInfo)e.ListItem).Name);
};
Why don't you just always Add(fileInfo.FullName) ?