Access denied on subFolders of windows in C# - c#

I need to search few files under C:\windows folder but I am getting error on lots of folders like "Access denied".
I am admin on the system and I also tried running visual studio as administrator but nothing helped.
here is my code...
var exes = File.ReadAllLines("ListOfExes.txt");
var output = new Dictionary<string, string>();
var sb = new StringBuilder();
var seachLocation = #"c:\windows";
FileIOPermission FilePermission = new FileIOPermission(FileIOPermissionAccess.AllAccess, seachLocation);
try
{
FilePermission.Demand();
FilePermission.Assert();
foreach (var exe in exes)
{
string[] files = Directory.GetFiles(seachLocation, exe.Trim(), SearchOption.AllDirectories);
if (files.Length > 0 && !output.ContainsKey(exe.Trim()))
{
foreach (var f in files)
Console.WriteLine(f);
}
}
CodeAccessPermission.RevertAssert();
}
catch (SecurityException)
{
Console.WriteLine("You do not have permission to read this directory.");
}
my code works fine on any other folder except windows one.
If I go to the path for access denied using windows explorer then it gave me a prompt for access and if I click on continue then it let me go inside the folder.
I understand this is happening because security design but is there any way to make search in entire windows folder if I have admin rights.
I need to use the code as I have thousands of file to search and note their path in windows directory.

Related

c# deleting empty folder

I have the following code and I am trying to delete a folder it works most of the time but occasionally I get an IOException and visual studio says "access denied" The path exist and the folder says it is empty, and no subfolders but I can not delete it using the following code. Any suggestion why this would work most of the time but not always and how to fix it
if ( Directory.Exist( dir2 + "\\Inv")
{
System.IO.DirectoryInfo dirinv = new System.IO.DirectoryInfo(dir2 + "\\Inv");
setAttributesNormal(dirinv);
try
{
Directory.Delete(dir2 + "\\Inv", true);
}
catch (IOException)
{
Directory.Delete(dir2 + "\\Inv", true);
}
catch (UnauthorizedAccessException)
{
Directory.Delete(dir2 + "\\Inv", true);
}
}
}
private void setAttributesNormal(DirectoryInfo dir)
{
foreach (var subDir in dir.GetDirectories())
setAttributesNormal(subDir);
foreach (var file in dir.GetFiles())
{
file.Attributes = FileAttributes.Normal;
}
}
Run the program (or if running in Visual Studio, then Visual Studio) by File Explorer Run as Administrator by right clicking on the app.
Visual Studio does not run as admin when one launches it. One must run it with elevated privlidges to do such operations on protected folders or to have access to the ports such as running IE Express from Visual Studio.

Application: Application Launcher, can't Move directory, it's being used by another process

I'm writing application launcher as a Window Application in C#, VS 2017. Currently, having problem with this piece of code:
if (System.IO.Directory.Exists(extractPath))
{
string[] files = System.IO.Directory.GetFiles(extractPath);
string[] dirs = Directory.GetDirectories(extractPath);
// Copy the files and overwrite destination files if they already exist.
foreach (string s in files)
{
// Use static Path methods to extract only the file name from the path.
var fileName = System.IO.Path.GetFileName(s);
var destFile = System.IO.Path.Combine(oldPath, fileName);
System.IO.File.Move(s, destFile);
}
foreach (string dir in dirs)
{
//var dirSplit = dir.Split('\\');
//var last = dirSplit.Last();
//if (last != "Resources")
//{
var fileName = System.IO.Path.GetFileName(dir);
var destFile = System.IO.Path.Combine(oldPath, fileName);
System.IO.Directory.Move(dir, destFile);
//}
}
}
I'm getting well known error
"The process cannot access the file 'XXX' because it is being used by another process."
I was looking for solution to fix it, found several on MSDN and StackOvervflow, but my problem is quite specific. I cannot move only 1 directory to another, which is Resources folder of my main application:
Here is my explanation why problem is specific:
I'm not having any issues with moving other files from parent directory. Error occurs only when loop reaches /Resources directory.
At first, I was thinking that it's beeing used by VS instantion, in which I've had main app opened. Nothing have changed after closing VS and killing process.
I've copied and moved whole project to another directory. Never opened it in VS nor started via *.exe file, to make sure that none of files in new, copied directory, is used by any process.
Finally, I've restarted PC.
I know that this error is pretty common when you try to Del/Move files, but in my case, I'm sure that it's being used only by my launcher app. Here is a little longer sample code to show what files operation I'm actually doing:
private void RozpakujRepo()
{
string oldPath = #"path\Debug Kopia\Old";
string extractPath = #"path\Debug Kopia";
var tempPath = #"path\ZipRepo\RexTempRepo.zip";
if (System.IO.File.Exists(tempPath) == true)
{
System.IO.File.Delete(tempPath);
}
System.IO.Compression.ZipFile.CreateFromDirectory(extractPath, tempPath);
if (System.IO.Directory.Exists(oldPath))
{
DeleteDirectory(oldPath);
}
if (!System.IO.Directory.Exists(oldPath))
{
System.IO.Directory.CreateDirectory(oldPath);
}
if (System.IO.Directory.Exists(extractPath))
{
string[] files = System.IO.Directory.GetFiles(extractPath);
string[] dirs = Directory.GetDirectories(extractPath);
// Copy the files and overwrite destination files if they already exist.
foreach (string s in files)
{
// Use static Path methods to extract only the file name from the path.
var fileName = System.IO.Path.GetFileName(s);
var destFile = System.IO.Path.Combine(oldPath, fileName);
System.IO.File.Move(s, destFile);
}
foreach (string dir in dirs)
{
//var dirSplit = dir.Split('\\');
//var last = dirSplit.Last();
//if (last != "Resources")
//{
var fileName = System.IO.Path.GetFileName(dir);
var destFile = System.IO.Path.Combine(oldPath, fileName);
System.IO.Directory.Move(dir, destFile);
//}
}
}
string zipPath = #"path\ZipRepo\RexRepo.zip";
ZipFile.ExtractToDirectory(zipPath, extractPath);
}
And now, my questions:
Can it be related to file types (.png, .ico, .bmp) ?
Can it be related to fact, that those resources files are being used like, as, for example .exe file icon in my main application? Or just because those are resources files?
Is there anything else what I'm missing and what can cause the error?
EDIT:
To clarify:
There are 2 apps:
Main Application
Launcher Application (to launch Main Application)
And Resources folder is Main Application/Resources, I'm moving it while I'm doing application version update.
It appeared that problem is in different place than in /Resources directory. Actually problem was with /Old directory, because it caused inifinite recurrence.

How to Set File Access Permission for Scanning All Files in C#

I am Trying to write a Functionality where i could get the Complete List of All File Name in all Drives,but I am stuck in a place where its giving me security exception to read all files.
I went through many of the articles in this site and the other, but unable to figure out how to set complete access rights
this post was much useful but i am getting an Exception which was unanswered in that thread
How to grant read access to all files in a folder and subfolders using c#?
Now My code looks like this
[FileIOPermission(SecurityAction.LinkDemand, Read = "C:\\")]
public void GetAllFilesFromPhysicalDrives()
{
List<DriveInfo> allphydrives = GetListofPhysicalDrivesOnly(); //Gets All Physical DrivesCollection
try
{
foreach (DriveInfo dr in allphydrives)
{
DirectoryInfo dir = new DirectoryInfo(dr.Name);
DirectorySecurity dirSecurity = dir.GetAccessControl();
dirSecurity.AddAccessRule(new FileSystemAccessRule(Environment.UserName, FileSystemRights.Read, AccessControlType.Allow));
dir.SetAccessControl(dirSecurity);
FileSystemAccessRule faRule;
FileSystemRights fsrRights;
DirectorySecurity dirsec;
fsrRights = FileSystemRights.FullControl;
faRule = new FileSystemAccessRule(new System.Security.Principal.NTAccount("my-pc\\me"),fsrRights,InheritanceFlags.ObjectInherit | InheritanceFlags.ContainerInherit,PropagationFlags.InheritOnly, AccessControlType.Allow);
System.Security.Principal.NTAccount account = new System.Security.Principal.NTAccount("me\\me");
dirsec = Directory.GetAccessControl("C:\\");
dirsec.SetOwner(account);
dirsec.AddAccessRule(faRule);
Directory.SetAccessControl("C:\\", dirsec);
}
}
catch(Exception ex)
{
}
}
so when the code to set the access executes i am getting an "Attempt to Perform UnAuthorized Operation" Exception
I don't want to set Permission for files one by one because its a tedious task so help me which would happen dynamically via code for All folders so that i could iterate and get all file names .(I don't intend to get windows related files or kernal files ,just the user created files is enough)

Directory.Delete doesn't work. Access denied error but under Windows Explorer it's ok

I have searched the SO but find nothing.
Why this doesn't work?
Directory.Delete(#"E:\3\{90120000-001A-0000-0000-0000000FF1CE}-C");
Above line will throw exception "Access is denied". I have admin rigths and I can delete the dir with Explorer.
It looks like some forbidden chars? but Windows Explorer can handle it. How can I delete directories with names like that?
Thank you all for your input, it helps me in quick find of solution.
As Phil mentioned "Directory.Delete fails if it is, regardless of permissions (see bottom of msdn.microsoft.com/en-us/library/…)"
In addition Unable to remove Read-Only attribute from folder
Microsoft says:
You may be unable to remove the
Read-Only attribute from a folder
using Windows Explorer. In addition,
some programs may display error
messages when you try to save files to
the folder.
Conclusion: always remove all dir,file attributes diffrent then Normal before deleting. So below code solve the problem:
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(#"E:\3\{90120000-0021-0000-0000-0000000FF1CE}-C1");
if (dir.Exists)
{
setAttributesNormal(dir);
dir.Delete(true);
}
. . .
function setAttributesNormal(DirectoryInfo dir) {
foreach (var subDir in dir.GetDirectories())
setAttributesNormal(subDir);
foreach (var file in dir.GetFiles())
{
file.Attributes = FileAttributes.Normal;
}
}
I used binball's code and added one line to set the directory attributes to normal also.
if (dir.Exists)
{
setAttributesNormal(dir);
dir.Delete(true);
}
function setAttributesNormal(DirectoryInfo dir)
{
foreach (var subDir in dir.GetDirectories())
{
setAttributesNormal(subDir);
subDir.Attributes = FileAttributes.Normal;
}
foreach (var file in dir.GetFiles())
{
file.Attributes = FileAttributes.Normal;
}
}
Based on the directory you are working in, you will probably need administrator access to delete files. To test this, run your app as administrator from explorer and see if it works (right-click the .exe and choose "Run As Administrator").
If that works, you'll need to get administrator privileges when your application executes. You can do this by adding the following to your application manifest:
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
<security>
<requestedPrivileges>
<requestedExecutionLevel level="requireAdministrator" />
</requestedPrivileges>
</security>
</trustInfo>
Adding to #binball and #Chuck answer. Here is a somewhat quick async-friendly implementation of setAttributesNormal() using BFS to traverse directories.
It's ideal for deep directory traversal, where recursion may fill call stack.
internal static void SetAttributesNormal(DirectoryInfo path) {
// BFS folder permissions normalizer
Queue<DirectoryInfo> dirs = new Queue<DirectoryInfo>();
dirs.Enqueue(path);
while (dirs.Count > 0) {
var dir = dirs.Dequeue();
dir.Attributes = FileAttributes.Normal;
Parallel.ForEach(dir.EnumerateFiles(), e => e.Attributes = FileAttributes.Normal);
foreach (var subDir in dir.GetDirectories())
dirs.Enqueue(subDir);
}
}
Have you tried to create a new instance of the DirectoryInfo class, and then checking the exists before the delete? The code would look like this:
System.IO.DirectoryInfo dir = new System.IO.DirectoryInfo(#"E:\3\{90120000-001A-0000-0000-0000000FF1CE}-C");
if (dir.Exists)
dir.Delete(true);
Also, please verify that you (the user running the application) has access to the folder. If this is a network mapped drive, it will need to be able to be deleted by the user running the application.
Hope this helps!
I had this symptom, and it actually was explorer.exe itself that was locking the directory. I found this using handle.exe, but one can also use powershell to find which process is locking the file:
$lockedFile = "C:\Windows\System32\wshtcpip.dll"
Get-Process | foreach{$processVar = $_; $_.Modules | foreach { if ($_.FileName -like "${lockedFile}*") { $processVar.Name + " PID:" + $processVar.id + " [" + $_.Filename + "]"}}}
You then have to decide whether to try to stop that process gracefully or not; it would be easy to modify the powershell script to try to kill any processes locking the file:
$lockedFile = "C:\directory_I_want_to_delete"
Get-Process | foreach{$processVar = $_; $_.Modules | foreach { if ($_.FileName -like "${lockedFile}*") { write-host $processVar.Name + " PID:" + $processVar.id + " [" + $_.Filename + "]" ; write-host "Killing process..." ; stop-process -pid $processVar.id -force }}}

UnauthorizedAccessException in my own directory

I'm trying to iterate over the items on my start menu, but I keep receiving the UnauthorizedAccessException. I'm the directory's owner and my user is an administrator.
Here's my method (it's in a dll project):
// root = C:\Users\Fernando\AppData\Roaming\Microsoft\Windows\Start Menu
private void walkDirectoryTree(DirectoryInfo root) {
try {
FileInfo[] files = root.GetFiles("*.*");
foreach (FileInfo file in files) {
records.Add(new Record {Path = file.FullName});
}
DirectoryInfo[] subDirectories = root.GetDirectories();
foreach (DirectoryInfo subDirectory in subDirectories) {
walkDirectoryTree(subDirectory);
}
} catch (UnauthorizedAccessException e) {
// do some logging stuff
throw; //for debugging
}
}
The code fail when it starts to iterate over the subdirectories. What else should I do? I've already tried to create the manifest file, but it didn't work.
Another point (if is relevant): I'm just running some unit tests with visual studio (which is executed as administrator).
Based on your description, it appears there is a directory to which your user does not have access when running with UAC enabled. There is nothing inherently wrong with your code and the behavior in that situation is by design. There is nothing you can do in your code to get around the fact that your account doesn't have access to those directories in the context it is currently running.
What you'll need to do is account for the directory you don't have access to. The best way is probably by adding a few extension methods. For example
public static FileInfo[] GetFilesSafe(this DirectoryRoot root, string path) {
try {
return root.GetFiles(path);
} catch ( UnauthorizedAccessException ) {
return new FileInfo[0];
}
}

Categories