question

WadhawanRishabh-6344 avatar image
0 Votes"
WadhawanRishabh-6344 asked karenpayneoregon answered

Encountering System.UnauthorizedAccessException when trying to delete a file.

Hi All,
I am encountering System.UnauthorizedAccessException while trying to delete a file even though the file is not marked as read only and the user has all the required access for that file. Can someone help me in identifying the other possible root cause for getting this exception on File.Delete() method and also help me with the resolutions for the same.

dotnet-csharpdotnet-runtime
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.


Maybe the file is in use. Can you delete the file manually or if you re-execute your code after a short delay?


0 Votes 0 ·

i Read it in Microsoft documentation that if the file is in use we get Exception type: IOException and not System.UnauthorizedAccessException.
I am not sure whether that is correct or not.?
And once I get this exception i keep getting it while trying to delete the file through my code.

0 Votes 0 ·
Viorel-1 avatar image Viorel-1 WadhawanRishabh-6344 ·

The documentation mentions that if the file is an executable, then the exception is UnauthorizedAccessException. Therefore, you should receive IOException in case of non-executables.

Are you able to delete the file manually, or programmatically after a system restart?

Maybe also show some details about the kind, location and origin of these files.

0 Votes 0 ·
Show more comments
karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered WadhawanRishabh-6344 commented

Hello,

There are several reasons for this excluding permissions e.g. an anti-virus program considers the action being performed by malware, the path/file name points to a non-existing file (a flaw in your code) are two examples.

Try the following a provide what has been written to the console (and if this is .NET Core replace Console with Debug). If not using a console app, add the code to existing code.

 class Program
 {
     static void Main(string[] args)
     {
         var path = "c:\\temp\\readonly.txt";
         try
         {
             File.Delete(path);
         }
         catch (UnauthorizedAccessException e)
         {
             Console.WriteLine(e);
         }
     }
 }
· 4
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

Hi karenpayneoregon,

I have a File.Exists() check before trying to delete the file. So i think i can remove the possibility of the file not being present right.?

0 Votes 0 ·
Viorel-1 avatar image Viorel-1 WadhawanRishabh-6344 ·

I have a File.Exists() check before trying to delete the file.

According to documentation, File.Exists() is not required before File.Delete().

0 Votes 0 ·

If the file was generated while running the same app that is attempting to delete the file then it's possible the handle to the file is still in use

If saying a StreamWriter make use it done as follows with adjustment to FileMode as needed.

 using (StreamWriter sw = new StreamWriter(File.Open(path, System.IO.FileMode.Append))) 
 {
 }


0 Votes 0 ·

Ill try to explain it more clearly.
We do the following in sequential order
1. Create a temp file using stream writer
2. Delete the bkp file if it exists
3. File.Move(xmlfile,bkpfile)
4. File.Move(tempfile,xmlfile)

Also we have a locking mechanism to ensure that only one thread is able to run the above sequence of statements.

0 Votes 0 ·
karenpayneoregon avatar image
0 Votes"
karenpayneoregon answered

Unfortunately my only code sample is in VB.NET. If you like to examine the full source, see my GitHub repository and full explanation in this Microsoft article.

Here is the core code translated from VB where line 80 is the key. What this does is ensures the temp file is deleted and that the only reason it would not be deleted is if the computer power was turned off before the app can close.

 using System;
 using System.IO;
 using System.Text;
 using DeleteFileOnClose.LanguageExtensions;
 using DeleteFileOnClose.Modules;
    
 namespace Classes
 {
     public class FileOperations
     {
    
         public event PeekEventHandler PeekEventHandler;
         public event CustomersEventHandler CustomersEventHandler;
    
         private FileStream _creator1;
    
         /// <summary>
         /// Setup FileStream with a random file name marked
         /// to remove on app crash or normal close of app.
         /// </summary>
         public FileOperations()
         {
    
             _creator1 = FileStreamDeleteOnClose(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "K1".GenerateRandomXmlFile(5)));
    
         }
         public void Crash(string line)
         {
             var fileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Crashed.txt");
    
             try
             {
                 using (FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite))
                 {
                     using (StreamWriter fw = new StreamWriter(fs))
                     {
                         fw.Write(line);
                     }
                 }
    
                 Environment.FailFast(null);
    
                 //
                 // never get here
                 //
                 var crashVar = int.Parse(line);
    
                 File.Delete(fileName);
    
             }
             catch (Exception ex)
             {
                 //
                 // never get here
                 //
                 if (File.Exists(fileName))
                 {
                     File.Delete(fileName);
                 }
    
             }
    
         }
         public void QuickUse(List<Person> peopleList, bool failFast = false)
         {
    
             var fileName = Path.GetTempFileName();
    
             if (failFast)
             {
                 Console.WriteLine(fileName);
             }
    
    
             if (PeekEventHandler != null)
                 PeekEventHandler(this, new PeekArgs($"Temporary file name: {fileName}"));
             if (PeekEventHandler != null)
                 PeekEventHandler(this, new PeekArgs(""));
    
             using (var fileStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose))
             {
    
                 using (var streamWriter = new StreamWriter(fileStream))
                 {
    
                     //
                     // Write each person comma delimited
                     //
                     for (int index = 0; index < peopleList.Count; index++)
                     {
                         if (index == 1 && failFast)
                         {
                             Console.WriteLine("Fail");
                             Environment.FailFast(null);
                         }
                         streamWriter.WriteLine($"{peopleList[index].FirstName},{peopleList[index].LastName}");
                     }
    
                     streamWriter.Flush();
    
                     //
                     // Read data back
                     //
    
                     StreamReader streamReader = null;
    
                     streamReader = new StreamReader(fileStream);
                     streamReader.BaseStream.Seek(0, SeekOrigin.Begin);
    
                     while (streamReader.Peek() > -1)
                     {
    
                         var nameParts = streamReader.ReadLine().Split(',');
    
                         if (PeekEventHandler != null)
                             PeekEventHandler(this, new PeekArgs($"{nameParts[0]} - {nameParts[1]}"));
    
                     }
    
                 }
    
             }
    
         }
         /// <summary>
         /// Initial population of file
         /// </summary>
         public void PopulateTempFile()
         {
             XDocument xmlData = System.Xml.Linq.XElement.Parse("<?xml version=\"1.0\" standalone=\"yes\"?><Customers><Customer><CustomerID>100</CustomerID><CompanyName>Alfreds Futterkiste</CompanyName></Customer><Customer><CustomerID>101</CustomerID><CompanyName>Ana Trujillo Emparedados y helados</CompanyName></Customer><Customer><CustomerID>102</CustomerID><CompanyName>Bilido Comidas preparadas</CompanyName></Customer><Customer><CustomerID>103</CustomerID><CompanyName>Centro comercial Moctezuma</CompanyName></Customer></Customers>");
    
             byte[] byteArray = Encoding.ASCII.GetBytes(xmlData.ToString());
    
             _creator1.Write(byteArray, 0, byteArray.Length);
    
         }
         /// <summary>
         /// Add a new Customer to the file then read the
         /// file contents back
         /// </summary>
         /// <param name="newCustomer"></param>
         public void AddNewCustomer(Customer newCustomer)
         {
             if (_creator1.Length == 0)
             {
                 PopulateTempFile();
             }
    
             _creator1.Position = 0;
    
             StreamReader streamReader = null;
             streamReader = new StreamReader(_creator1);
             streamReader.BaseStream.Seek(0, SeekOrigin.Begin);
    
             StringBuilder customerDataBuilder = new StringBuilder();
    
             while (streamReader.Peek() > -1)
             {
                 customerDataBuilder.Append(streamReader.ReadLine());
             }
    
    
             var customersLambdaTyped = (
                 from customer in XDocument.Parse(customerDataBuilder.ToString()).Descendants("Customer")
                 select customer).Select((customer) =>
                 {
                     return new Customer
                     {
                         Name = customer.Elements("CompanyName").Value,
                         Identifier = Convert.ToInt32(customer.Elements("CustomerID").Value)
                     };
                 }).ToList();
    
    
             //
             // Get last identifier and increment by 1
             // Since we have an exclusive lock there are no 
             // issues of colliding with another section of code
             // grabbing the same identifier
             //
             var id = customersLambdaTyped.Select((customer) => customer.Identifier).Max() + 1;
    
             newCustomer.Identifier = id;
    
             //
             // Add customer to existing list
             //
             customersLambdaTyped.Add(newCustomer);
    
             //
             // Transform to XML using xml literals and embedded expressions
             //
             XDocument doc = System.Xml.Linq.XElement.Parse("<?xml version=\"1.0\" standalone=\"yes\"?><Customers>" +
                 from currentCustomer in customersLambdaTyped
                 select System.Xml.Linq.XElement.Parse("<Customer><CustomerID>" + currentCustomer.Identifier + "</CustomerID><CompanyName>" + currentCustomer.Name + "</CompanyName></Customer>") + "</Customers>");
    
             doc.Declaration.Version = "1.0";
             doc.Declaration.Encoding = "utf-8";
    
             //
             // Rewrite the file rather than appending
             //
             byte[] byteArray = Encoding.ASCII.GetBytes(doc.ToString());
             _creator1.SetLength(0);
             _creator1.Write(byteArray, 0, byteArray.Length);
    
             ExamineCustomersFromXmlFile();
    
         }
         public void ExamineCustomersFromXmlFile()
         {
    
             if (_creator1.Length == 0)
             {
                 PopulateTempFile();
             }
    
             //
             // Rewind to start of temporary file
             //
             _creator1.Position = 0;
    
             //
             // Read data from  temporary file into a StringBuilder
             // to parse into either a anonymous type or strong typed
             // list.
             //
             StreamReader streamReader = null;
             streamReader = new StreamReader(_creator1);
             streamReader.BaseStream.Seek(0, SeekOrigin.Begin);
    
             StringBuilder customerDataBuilder = new StringBuilder();
    
             while (streamReader.Peek() > -1)
             {
                 customerDataBuilder.Append(streamReader.ReadLine());
             }
    
             //
             // Example of reading data anonymously and strong typed
             //
    
    
             var customersLinqAnonymous = (
                 from customer in XDocument.Parse(customerDataBuilder.ToString()).Descendants("Customer")
                 select new
                 {
                     Name = customer.Elements("CompanyName").Value,
                     Identifier = Convert.ToInt32(customer.Elements("CustomerID").Value)
                 }).ToList();
    
             var customersLambdaTyped = (
                 from customer in XDocument.Parse(customerDataBuilder.ToString()).Descendants("Customer")
                 select customer).Select((customer) =>
                 {
                     return new Customer
                     {
                         Name = customer.Elements("CompanyName").Value,
                         Identifier = Convert.ToInt32(customer.Elements("CustomerID").Value)
                     };
                 }).ToList();
    
    
    
             if (CustomersEventHandler != null)
                 CustomersEventHandler(this, new CustomerArgs(customersLambdaTyped));
    
         }
    
     }
 }


5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.