Determining a FileAttribute for a file in case of "Access Denied": - c#

In my network, there are some files whose access is simply blocked.
A user cannot open nor read the file.
When I try to open the file, the only message that I get is "Access Denied".
bool isReadOnly = ((File.GetAttributes(Path) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly);
I tried other options available under FileAttributes class. Nothing is matched for "Access Denied".
In short, how do I know whether a file is access-denied to me or not in c#. I am using WPF and visual studio .net 2010
Whenever I try to access it through code, I simply get an exception. When I try to open it manually I get something like "Access Denied."
try
{
IEs = from file in Directory.EnumerateFiles(sDirectoryToBeSearched, sValidExtensions, SearchOption.AllDirectories)
from str in File.ReadLines(file)
where (str.IndexOf(sSearchItem, StringComparison.OrdinalIgnoreCase) >= 0)
select file;
}
catch
{
MessageBox ("Exception arised");
}
Even If used try catch, exception is not handled because of LINQ query. Any solutions ?>

Instead of using LINQ try using recursion, that way if a file or folder access is denied the rest of procedure will continue. Example bellow.
private void SearchDirectory(string folder)
{
foreach (string file in Directory.GetFiles(folder))
{
try
{
// do work;
}
catch
{
// access to the file has been denied
}
}
foreach (string subDir in Directory.GetDirectories(folder))
{
try
{
SearchDirectory(subDir);
}
catch
{
// access to the folder has been denied
}
}
}

You don't have to check the FileAttributes, you need to check the security lists.
You can look at the example here to see how to work with the FileSecurity class.

Related

How to skip files that are in use by another process during programmatic deletion?

I am trying to program a Windows service that automatically deletes the file from a specific folder. But I encountered an error:
Cannot access the file. The file is currently in use by another process/program.
I tried to do the following, but still get the same error.
string[] files = Directory.GetFiles(#"C:\Users\ASIM\AppData\Local\Temp");
// string[] directories = Directory.GetDirectories(#"C:\Users\ASIM\AppData\Local\Temp", "p*", SearchOption.TopDirectoryOnly);
if (files != null || files.Length != 0)
{
{
foreach (string f in files)
{
try
{
File.Delete(f);
}
finally { }
}
}
}
so how to skip deleting a file if it is in use?
There is no point checking if the file is deletable before deleting it because there will be a small window of opportunity between your check and the delete, where another process will open the file. The best idea is to try and delete it and handle the exception if it occurrs.
Your try/finally should be try/catch with the appropriate exception:
try
{
File.Delete(f);
}
catch(IOException ex)
{
// Probably some logging here
}

Access denied - Trying to delete all files in a folder

I'm currently trying to delete all files in a folder (Recently opened files), but without any luck, I get the message: "Access to the path 'C:\Users\User\Recent' is denied." . I've been looking around to see if there were any solutions, but unfortunately I can't find anything.
String recent = Environment.ExpandEnvironmentVariables("%USERPROFILE%") + "\\Recent";
EmptyFolderContents(recent);
private void EmptyFolderContents(string folderName)
{
foreach (var Folder in Directory.GetDirectories(folderName))
{
try
{
Directory.Delete(Folder, true);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
foreach (var Files in Directory.GetFiles(folderName))
{
try
{
File.Delete(Files);
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
}
}
}
The reason you are getting the Access Denied error is because you can't just delete files from that folder. They are virtual paths to real files. There is probably a better way to do what you are doing.
Here is an alternative that I found here. It uses WinAPI, which is never fun, but it works.
//you'll need to add this.
using System.Runtime.InteropServices;
[DllImport("shell32.dll")]
public static extern void SHAddToRecentDocs(ShellAddToRecentDocsFlags flag, IntPtr pidl);
public enum ShellAddToRecentDocsFlags
{
Pidl = 0x001,
Path = 0x002,
}
//then call this from your method
SHAddToRecentDocs(ShellAddToRecentDocsFlags.Pidl, IntPtr.Zero);
Your error message seems to show that you're missing a backslash:
Access to the path 'C:Users\User\Recent' is denied.
(after the C:)
I Use Permissions Time Machine v1.1 to restore default permissions and remove "Access is denied" message for folder or files or registry keys or windows services or wmi objects it's free and fast and easy
download it from amyd projects blog

C# treeview Unauthorized exception

So I followed MS article http://msdn.microsoft.com/en-us/library/ms171645.aspx
This is Creating an Explorer Style Interface with the ListView and TreeView Controls Using the Designer.
So all is well, howerver, is you set it to the root of C to scan all the folders and files etc. I receive {"Access to the path '<path to file' is denied."}
VS 2010 points this spot that is the issue.
subSubDirs = subDir.GetDirectories();
I can put a try catch around this are, howerver, after the exception is thrown the app doesn't continue.
Is there a way I can skip directories that the app cannot access?
You might have the try catch in the wrong place. Based on the code in the walkthrough you could put the try catch like this:
Replace:
subSubDirs = subDir.GetDirectories();
with this:
try
{
subSubDirs = subDir.GetDirectories();
}
catch(UnauthorizedAccessException uae)
{
//log that subDir.GetDirectories was not possible
}
Also, the line:
if (subSubDirs.Length != 0)
should be changed to:
if (subSubDirs != null && subSubDirs.Length != 0)
You get the exception because the calling account doesn't have access rights to folders like System Volume Information. You can get around this some by using Linq and skipping folders that are marked System or Hidden.
DirectoryInfo root = new DirectoryInfo(#"C:\");
Func<FileSystemInfo, Boolean> predicate = dir =>
(dir.Attributes & FileAttributes.System) != FileAttributes.System &&
(dir.Attributes & FileAttributes.Hidden) != FileAttributes.Hidden;
IEnumerable<FileSystemInfo> directories = root.GetDirectories().Where(predicate);
foreach (DirectoryInfo directory in directories) {
try {
Trace.WriteLine(directory.Name);
DirectoryInfo[] subdirectories = directory.GetDirectories();
}
catch (System.UnauthorizedAccessException) {
Trace.WriteLine("Insufficient access rights.");
}
}
Trace.WriteLine("End of application.");
This is not solution for every scenario though, and will fail on some files and folders. There is no easy solution using the existing API; you may want to look into getting file and directory information through WMI instead.

How do I prevent System.IO.Directory.Delete(pathtodelete, true) from giving me a "Directory is not empty" error?

I'm kinda new to working with C# .NET's System.IO namespace. So please forgive me for some basic questions.
I am writing an online interface that will allow a site owner to modify files and directories on the server.
I have gotten inconsistent performance out of System.IO.Directory.Delete(PathToDelete, true);. Sometimes it works great, sometimes it throws an error. My controller looks like this:
public ActionResult FileDelete(List<string> entity = null)
{
if (entity != null)
{
if (entity.Count() > 0)
foreach (string s in entity)
{
string CurrentFile = s.Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
string FileToDelete = Server.MapPath(CurrentFile);
bool isDir = (System.IO.File.GetAttributes(FileToDelete) & FileAttributes.Directory) == FileAttributes.Directory;
if (isDir)
{
if (System.IO.Directory.Exists(FileToDelete))
{
//Problem line/////////////////////////////////
System.IO.Directory.Delete(FileToDelete, true);
}
}
else
{
if (System.IO.File.Exists(FileToDelete))
{
System.IO.File.Delete(FileToDelete);
string ThumbConfigDir = ConfigurationManager.AppSettings["ThumbnailSubdirectory"];
string ThumbFileToDelete = Path.GetDirectoryName(FileToDelete) + Path.DirectorySeparatorChar + ThumbConfigDir + Path.DirectorySeparatorChar + Path.GetFileName(FileToDelete);
if (System.IO.File.Exists(ThumbFileToDelete))
{
System.IO.File.Delete(ThumbFileToDelete);
}
}
}
}
}
return Redirect(HttpContext.Request.UrlReferrer.AbsoluteUri.ToString());
}
Sometimes, I get an error when tring to delete directories that says:
The directory is not empty.
Description: An unhandled exception occurred during the execution of the current
web request. Please review the stack trace for more information about the error
and where it originated in the code.
Exception Details: System.IO.IOException: The directory is not empty.
Source Error:
Line 137: if (System.IO.Directory.Exists(FileToDelete))
Line 138: {
Line 139: System.IO.Directory.Delete(FileToDelete, true);
Line 140: }
Line 141: }
I'm not sure what kind of defensive coding I can implement to avoid get errors like these. Any thoughts? Am I missunderstanding what it means to set recursive to true by saying System.IO.Directory.Delete(FileToDelete, true);?
If there's a file that's in use, the Delete won't empty the directory, and then will fail when it will try to delete the directory.
Try using FileInfo instead of the static methods, and use Refresh after you do any action on the file. (or DirectoryInfo for direcotries)
Similar problem
In general you just have to expect this sort of exceptions from file/folder manipulation code. There is large number of reasons why it could happen - some file in use, some process have working folder set to the directory, some files are not visible to your process due to permissions and so on.
Process monitor ( http://technet.microsoft.com/en-us/sysinternals/bb896645.aspx) likely will show what causes the problem.
One of common reason if you create folder yourself for your temporary files and then try to delete it is to forget to dispose Stream objects related to files in such folder (could be indirect links by Reader and Writer objets, XmlDocument).

DirectoryNotFoundException when calling Directory.GetDirectories on Environment.SpecialFolder.Favorites due to Domain Folder Redirection

I have some C# code that tries to get the Favorites for the currently logged in user. The code is part of a Taskbar Toolbar that gets loaded into the Windows Explorer process. I have a user who is using Windows Vista with UAC enabled on a domain that either has Roaming Profiles or Folder Redirection setup and enabled. When calling Directory.GetDirectories on the Favorites path, it throws "System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\Users\\Favorites\". Other users on other domains that do not have Roaming Profiles or Folder Redirection setup do not have this issue.
The user also reported that copying the path from the failed logs into the run prompt fails to load the path, but if they navigate to the path directly using explorer and then copy and paste that path into the run prompt, it works. He sent me both paths and they are exactly identical which doesn't make any sense at all.
My theory is that this is caused by the Folder Redirection where that path is actually pointing to a share on the server but the redirection is failing when trying to access the subdirectories (of the directoryInfo returned from Directory.GetDirectories). The initial directory works but all subdirectories of the initial directory fail to redirect correctly.
Has anyone come across a situation like this and/or know a workaround to gain proper access to redirected folders?
private void GetFavorites()
{
try
{
System.IO.DirectoryInfo dirInfo = new System.IO.DirectoryInfo(Environment.GetFolderPath(Environment.SpecialFolder.Favorites));
AddFavorites(dirInfo);
}
catch
{
}
}
private void AddFavorites(DirectoryInfo dirInfo)
{
foreach (System.IO.FileInfo fileInfo in dirInfo.GetFiles("*.url"))
{
//string alias = fileInfo.Name.Replace(".url", "");
if (!ItemsBookmarks.ContainsKey(fileInfo.Name))
ItemsBookmarks.Add(fileInfo.Name, fileInfo.Name);
}
foreach (System.IO.FileInfo fileInfo in dirInfo.GetFiles("*.lnk"))
{
if (!ItemsBookmarks.ContainsKey(fileInfo.Name))
ItemsBookmarks.Add(fileInfo.Name, fileInfo.Name);
}
foreach (System.IO.DirectoryInfo objDir in dirInfo.GetDirectories())
{
AddFavorites(objDir);
}
}
Thanks,
John
I believe the problem you are experiencing is related to Reparse Points.
See: http://msdn.microsoft.com/en-us/library/bb513869.aspx
See: What is the best way to check for reparse point in .net (c#)?
The problem can be avoided by using the following syntax:
private void AddFavorites(string dirPath)
{
try
{
foreach (string fileName in Directory.GetFiles(dirPath, "*.*", SearchOption.TopDirectoryOnly))
{
//string alias = fileInfo.Name.Replace(".url", "");
if (!ItemsBookmarks.ContainsKey(fileInfo.Name))
{
ItemsBookmarks.Add(fileName);
}
}
foreach (string subDirName in Directory.GetDirectories(dirPath, "*.*", SearchOption.TopDirectoryOnly))
{
AddFavorites(objDir);
}
}
catch
{
//error getting files or subdirs... permissions issue?
//throw
}
}

Categories

Resources