I want to get all files and folders in Drive C.
In fact, I want a list of all the files on the drive. All the files along with their path.
I use this code .but encounters an error.
static void Main(string[] args)
{
System.IO.DriveInfo di = new System.IO.DriveInfo(#"C:\");
System.IO.DirectoryInfo dirInfo = di.RootDirectory;
System.IO.FileInfo[] fileNames = dirInfo.GetFiles("*.*");
System.IO.DirectoryInfo[] dirInfos = dirInfo.GetDirectories("*.*");
foreach (System.IO.DirectoryInfo d in dirInfos)
{
string[] filePaths = Directory.GetFiles(d.FullName, "*.*",
SearchOption.AllDirectories);
}
}
You can simply exclude directories that you can't access by searching them one by one and surrounding all of the searches with a try-catch block. Here is an example:
Console.WriteLine("Input search pattern (or empty to search all):");
string pattern = Console.ReadLine();
if (pattern == "")
{
pattern = "*";
}
List<string> allDirectories = new List<string>{ #"C:\" });
Stack<string> directories = new Stack<string>(allDirectories);
List<string[]> allFiles = new List<string[]>();
while (directories.Count > 0)
{
try
{
Console.WriteLine("Searching " + directories.Peek() + " for " + pattern);
foreach (string dir in Directory.GetDirectories(directories.Pop()))
{
directories.Push(dir);
allDirectories.Add(dir);
try
{
allFiles.Add(Directory.GetFiles(dir, pattern, SearchOption.TopDirectoryOnly));
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
}
}
}
catch (UnauthorizedAccessException e)
{
Console.WriteLine(e.Message);
}
}
Console.WriteLine("FINISHED");
This will collect all files into the allFiles list (as paths) and directories into the allDirectories list.
This runs for ~10 minutes for me, so don't debug to many times.
First thing you need to do is compiling your C# app with a manifest file that asks for root privileges (follow instructions from: How do I force my .NET application to run as administrator?).
Next, What you should do is achieve any kind of a user/running-app with admin permissions and let it start your C# app.
I think that if you'll do the above via an app with root privileges then no UAC will pop-up to the user when the C# app will start.
If your app don't have root permission you won't be able to read the directory tree of unauthorized folders.
C# is a managed language, which means C# counts on the operating system to run and for that reason it can't bypass the operating system. Even with root permission, the operating system will be aware of your app actions.
BUT if your target is to figure out if a C# dll can maliciously read the folder tree of C drive, I think it's possible:
You need to compile your C# code into a exe file with a manifest as I've described above.
Then, create a batch file that will start a CLR process with root privileges (it'll probably alert the user with a UAC prompt but a common user won't suspect the CLR).
Make sure your batch will run with the user privileges and not the default ones or the next step won't work.
Your batch should tell the clr to load C# exe and I believe either no UAC will be prompted or either the batch could accept on behalves of the user without any prompt.
4'. If I'm wrong, perhaps the article https://www.codeproject.com/Articles/607352/Injecting-NET-Assemblies-Into-Unmanaged-Processes#PuttingItAllTogether will help you inject the exe into the clr without a UAC prompt.
Let me know if you continued the research by my suggestion and what was the results :-)
Related
I want to search for a string in a file ,whose location i.e file and folder name in a computer is known to me. File can be present in any computer over the domain. There can be multiple occurrences of the file as well as the keyword.
This is the code I have written:
namespace newprog
{
class Program
{
static void Main(string[] args)
{
string[] dirs = Directory.Getfiles("C:\ABC");
Console.WriteLine("Results {0}", dirs.Length);
try
{
foreach (string dir in dirs)
{
Console.WriteLine(dir);
}
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
}
}
In the above code I have found files in a local directory i.e. ABC. But now I want search a particular file from all the computers over the whole domain and also need to check the presence of a keyword in those files found.
My domnain name is pqr.rst.com and I want know a file ab.txt. So how do I use the getfiles command.
What I know
I can generate the list of all computers in the domain in a text file.
I know how to search for a file in my local directories like I di above.
My question
How do I search occurrences of a file in the whole domain and then how
to check for a keyword in them.
Any help will be greatly appreciated. Thanks in advance.
So I am trying to find a Dynamic folder. We have made a game and the game has a sound driver which we provided for the players which is optional. When they download the new patch the driver also gets downloaded and put into a folder called Driver. It is a optional driver to install if one would like. I have the installation Registry Key of where it should be installed. I am asking how can I find the folder called Driver that is in the Game Folder that is downloaded but not ran because its optional. I am curios of how can I find that folder and than running the exe file inside that folder. The catch is, not everyone is going to have the folder installed in the same place. Some may have it on the C Driver, other maybe on the D drive and so on. So I am here to ask for some help. The Code is all being written in C#.
First off scanning the drives for a folder is very inefficient, so you may want to come up with a better way to limit your scan set. One way would be determine a relative path to search within. Following is my quick and dirty [NOTE: Please handle exceptions in a better way], also if possible concatenate your installation path to each local drive (this is assuming that you may only want to install your game on local drives) to limit the scan set.
static void Main(string[] args)
{
var myDrives = DriveInfo.GetDrives().Where(x => x.DriveType == DriveType.Fixed);
foreach (var drive in myDrives)
{
var outp = GetAllSubFolders(drive.Name,#"\Driver");
foreach (var folder in outp)
{
Console.WriteLine(folder);
}
}
}
static IEnumerable<string> GetAllSubFolders(string folder, string pathSubString)
{
try
{
var dirInfo = new DirectoryInfo(folder);
return dirInfo.GetDirectories().SelectMany(x => GetAllSubFolders(x.FullName, pathSubString))
.Concat(dirInfo.GetDirectories().Select(x => x.FullName).Where(x => x.Contains(pathSubString)));
}
catch
{
return new List<string>();
}
}
I'm using C# to get the exact path of the specific folder in windows system by giving the folder name. Is their any way to get the folder path by giving the folder name, where the folder name will be unique.
Update:
Folder is created at run time with current time as the name. This
process is done by the application. Here i know the folder name but i
didn't know path, because path is selected by the user during
installation and installation is done before very long time.
That changes the question considerably. Why not use the application to tell you where it lives:
http://msdn.microsoft.com/en-us/library/system.windows.forms.application.startuppath.aspx
I had a similar idea ages ago and wrote about it as a Code Project Tip:
http://www.codeproject.com/Tips/132804/Open-folders-using-a-Run-Command
Otherwise you would need to index every folder on the PC and make them unique names and look up the full path that way.
The other suggestion I have is using LogParser as the Most efficient way to find all exe files on disk using C#? Its a free Microsoft product but I'm not sure about re-dist permissions, I had to include it in my package separately last time I used it. It full on flys, faster than a speeding train!
I found a Log Parser example that finds folders, you could try it out and adapt it if its useful:
SELECT TOP 1 * FROM C:\TFS\Project\*.* WHERE INDEX_OF(Path, 'Database') > 0
The good folks over at http://visuallogparser.codeplex.com/ have
provided us with the source code.
Open the VisualLogParser solution in VS2010, ignore the prompt about debugging, after the solution loads, F5, set the combo-box to FS (FileSystem), paste in this query and press go.
You could probably use something like this, but it'll be rather slow, depending on how many folders needed to be looked through.
Use it like FindFullPath(rootFolder, folderNameToLookFor)
public static string FindFullPath(string path, string folderName)
{
if (string.IsNullOrWhiteSpace(folderName) || !Directory.Exists(path))
{
return null;
}
var di = new DirectoryInfo(path);
return findFullPath(di, folderName);
}
private static string findFullPath(DirectoryInfo directoryInfo, string folderName)
{
if (folderName.Equals(directoryInfo.Name, StringComparison.InvariantCultureIgnoreCase))
{
return directoryInfo.FullName;
}
try
{
var subDirs = directoryInfo.GetDirectories();
return subDirs.Select(subDir => findFullPath(subDir, folderName)).FirstOrDefault(fullPath => fullPath != null);
}
catch
{
// DirectoryNotFound, Security, UnauthorizedAccess
return null;
}
}
See following link
string dirName = new DirectoryInfo(#"c:\projects\roott\wsdlproj\devlop\beta2\text").Name;
if (Fubrowse.HasFile)
{
string path = Path.GetFullPath(Fubrowse.PostedFile.FileName);
//string root = Path.GetPathRoot(path);
GetFilesFromDirectory(path.Substring(0, path.LastIndexOf("\\")));
}
else
GeneralClass.ShowMessageBox("Please Select File First.");
}
private void GetFilesFromDirectory(string DirPath)
{
try
{
DirectoryInfo Dir = new DirectoryInfo(DirPath);
FileInfo[] FileList = Dir.GetFiles("*.cs", SearchOption.AllDirectories);
foreach (FileInfo FI in FileList)
Here, path is c:\windows\system32\inetsrv\config\. I want to get all sub directories's file name in FileList array.
The Windows account that's running your code needs read access to the folder (that typically requires admin rights).
If you're running the program from Visual Studio, that's your account. Run VS as administrator and your code should work should work.
If it's a web app, the app pool account needs read access to the folder.
If it's a windows service, the host account needs access.
I had the same issue. I couldn't get files from the C:\Windows\system32\intesrv\config because my system was 64 bit and my request redirect to C:\Windows\SysWOW64\system32\intesrv\config
More explanation is given by this answer.
PS. My answer is left here just for those who will be in search in future
I'm getting a Unauthorized Access Exception
in a file which I can delete manually.
in a folder where I'm able to delete by code other files
and the file isn't marked as read only
besides, I'm using Windows XP in a standalone PC and I have not assigned any permissions to the folder or the file.
no other process is using the file
If it helps, this is the code where the exception ocurrs:
protected void DeleteImage(string imageName)
{
if (imageName != null)
{
string f = String.Format("~/Images/{0}", imageName);
f = System.Web.Hosting.HostingEnvironment.MapPath(f);
if (File.Exists(f))
{
if (f != null) File.Delete(f);
}
}
}
Why could this happen?
I encountered the same problem, and found that writing my own Directory.Delete wrapper fixed it up. This is recursive by default:
using System.IO;
public void DeleteDirectory(string targetDir)
{
File.SetAttributes(targetDir, FileAttributes.Normal);
string[] files = Directory.GetFiles(targetDir);
string[] dirs = Directory.GetDirectories(targetDir);
foreach (string file in files)
{
File.SetAttributes(file, FileAttributes.Normal);
File.Delete(file);
}
foreach (string dir in dirs)
{
DeleteDirectory(dir);
}
Directory.Delete(targetDir, false);
}
If the directory contains a read only file, it won't delete that using Directory.Delete. It's a silly implementation by MS.
I am surprised no one suggested this method on the internet, which deletes the directory without recursing through it and changing every file's attributes. Here's that:
Process.Start("cmd.exe", "/c " + #"rmdir /s/q C:\Test\TestDirectoryContainingReadOnlyFiles");
(Change a bit to not to fire a cmd window momentarily, which is available all over the internet)
If it's not read-only it's possible that it is currently in use by another process.
Checking the obvious first...
When you open the file property and take a look at its security settings. Does the user running the code (i.e. if this is ASP.NET, Network Services / Domain Service Account) has access to actually delete the file?
If it is not, then change it and try again.
Are you running as administrator when trying to delete this manually?
If you are, then that's probably why you are able to delete it manually. Try deleting it as the account running your ASP.NET (I'm assuming it is ASP.NET since you are using System.Web.Hosting.HostingEnvironment.MapPath.)
If both failed, try to see if any other process is actually currently using this file. Good tool to find out is SysInternal Process Monitor. Filter it by path containing your filename and you should see if anything is using it. Terminate the process and try again.
I too faced the Same Problem but eventually came up with a Generic Approach. Below are my codes.
String pathfile = "C:\Users\Public\Documents\Filepath.txt" ;
if (!Directory.Exists(pathfile))
{
File.SetAttributes(pathfile, FileAttributes.Normal);
File.Delete(pathfile);
}
using (FileStream fs = File.Create(pathfile))
{
Byte[] info = new UTF8Encoding(true).GetBytes("What Ever Your Text is");
fs.Write(info, 0, info.Length);
File.SetAttributes(pathfile, FileAttributes.ReadOnly);
}
You, the human user, have a login with certain rights. The Web server might have a different login with different rights. A user starting with IUSR_XXXX or some such thing. Make sure that user has rights to the directory.
Without more info on the context in which you are deleting the file, I assume that the Web server user has different rights to a file than you do.