Unauthorized Access Exception while trying to write in AppData - c#

I am trying to copy a file from a remote computer in my AppData folder to then access this file whenever i want.
The copy works just fine when the destination path is GetCurrentDir(), but i got an exception every time i try to write elsewhere, in particular AppData.
pathToCopy = Path.Combine(Path.GetTempPath(), "imgTemp.jpg");//doesn't work
pathToCopy = Path.Combine(Directory.GetCurrentDirectory(), "imgTemp.jpg"); //works
And this is the code for my copy :
private void SaveImgTemp(string dest)
{
try
{
File.Copy(dest, pathToCopy, true);
if (File.Exists(pathToCopy))
{
Console.WriteLine("File copied successfully.");
}
}
catch (IOException e)
{
Console.WriteLine("An error occured: " + e.Message);
}
}
If anyone has an answer...
EDIT: Apparently, I have no rights to write anything under C:\Users.
I can write everywhere else in C:\ but as soon as I try to go in \Users, bam error thrown.
I don't exactly know why because I can copy whatever I want when I am not using my app.
Anyway, I think I will copy that elsewhere then.

You simply don't have write permissions to the app data folder. If you are debugging, you may need to run Visual Studio as administrator. Alternatively you can give read/write access to the AppData folder to your user.

Related

File.Delete fails silently - how to debug?

The following code fails to delete the file and prints file delete: so I know the file exists. With my app open I am able to delete the file in file explorer.
How can I debug this?
1) File permissions? My app created the file so should be able to delete? Regardless it would throw an exception and hit my catch debug message.
2) The file exists! According to the docs any other failure besides non-existence should be caught in my catch...
if (File.Exists(fn))
{
Debug.WriteLine("file delete: " + fn);
try
{
File.Delete(fn);
}
catch
{
Debug.WriteLine("Could not delete: " + fn);
}
} else {
Debug.WriteLine("File doesn't exist: "+fn);
}
The file is saved from a RichTextBox using the following code if this matters.
TextRange range;
FileStream fStream;
range = new TextRange(mNotepad.Document.ContentStart, mNotepad.Document.ContentEnd);
fStream = new FileStream(fn, FileMode.Create);
range.Save(fStream, DataFormats.XamlPackage);
fStream.Close();
Deleting a file does not provide a guarantee that the file will actually be removed from the file system. The file might have been opened by another process, which explicitly specified delete sharing. Very similar to read and write sharing. Also available in .NET, you'd pass FileShare.Delete to the FileStream constructor.
But the physical file can of course not be removed until all processes close the file. So it lingers beyond the File.Delete() call, can be seen by File.Exists() as well. Opening the file can no longer work, that will be rejected with access denied. Otherwise an excellent reason to never use File.Exists(), it has many problems.
If you want to find out what other process has the file opened then you can use a utility like SysInternals' Handle or Process Explorer. Expect to find back a program like a virus scanner or search indexer, could be anything however. Like a .NET program :)
From MSDN:
If the file to be deleted does not exist, no exception is thrown.
Make sure your path exists. I know you said you did, but check again.
Make sure you reach the actual File.Delete line
Cheers
I had the same issue before, follow the steps to see if it helps you. As silly as it may sound. Make sure no processes other than yours are making use of that file you created? Is this application multi-threaded? Do you have services running that use the file?
Make sure your not in debug mode, and do a Build - Clean
Check that the file is still at the location and copy the file path.
Put a break point right before file deletion.
Rebuild your project after you put your break-point.
Press F5 to debug and step through the code.
Check that the file path matches the one that you have.
I tried to reproduce similar situation with my own code
string fn = #"C:\Users\Public\Pictures\Sample Pictures\Desert - Copy.jpg";
//The file is locked by Image.FromFile
Image img = Image.FromFile(fn);
//If img.Dispose() here, then file is unlocked and can be deleted
if (File.Exists(fn))
{
try
{
File.Delete(fn);
Debug.WriteLine("file delete: " + fn);
}
catch
{
//Caught
Debug.WriteLine("Could not delete: " + fn);
}
}
else
{
Debug.WriteLine("File doesn't exist: " + fn);
}
I found the file is locked by Image.FromFile() and therefore Could not delete.
For the same reason, I believe your file with path fn is locked by the Filestream ftream
Can you try to do
fStream.Dispose();
before your delete process and rerun the program to see if you can delete the file? thanks. You can dispose the fstream and create a new one if needed,right?

Directory.Move(): Access to Path is Denied

I'm writing this Windows Form Application in Visual Studio 2010 using C#.
There is a Execute button on the form, the user will hit the button, the program will generate some files and are stored in the Output folder (which is created by the program using Directory.CreateDirectory())
I want to create an Archive folder to save the output files from previous runs.
In the beginning of each run, I try to move the existing Output folder to the Archive folder, then create a new Output folder. Below is the function I ran to move directory.
static void moveToArchive()
{
if (!Directory.Exists("Archive")) Directory.CreateDirectory("Archive");
string timestamp = DateTime.Now.ToString("yyyyMMddHHmms");
try
{
Directory.Move("Output", "Archive\\" + timestamp);
}
catch(Exception e)
{
Console.WriteLine("Can not move folder: " + e.Message);
}
}
The problem I ran into confuses me a lot...
There are some times that I can successfully move the Output folder to archive, but sometimes it fails.
The error message I got from catching the exception is Access to path 'Output' is denied.
I have checked that all the files in the Output folder are not in use. I don't understand how access is denied sometimes and not all the times.
Can someone explain to me and show me how to resolve the problem?
--Edit--
After HansPassant comment, I modified the function a little to get the current directory and use the full path. However, I'm still having the same issue.
The function now looks like this:
static void moveToArchive()
{
string currentDir = Environment.CurrentDirectory;
Console.WriteLine("Current Directory = " + currentDir);
if (!Directory.Exists(currentDir + "\\Archive")) Directory.CreateDirectory(currentDir + "\\Archive");
string timestamp = DateTime.Now.ToString("yyyyMMddHHmms");
try
{
Directory.Move(currentDir + "\\Output", currentDir + "\\Archive\\" + timestamp);
}
catch(Exception e)
{
Console.WriteLine("Can not move folder: " + e.Message);
}
}
I printed out the current directory and it is just as what I was expecting, and I'm still having trouble using full path. Access to path 'C:\Users\Me\Desktop\FormApp\Output' is denied.
--Edit--
Thank you everyone for answering and commenting.
I think some of you miss this part so I'm going stress it a bit more.
The Directory.Move() sometimes work and sometimes fails.
When the function succeed, there was no problem. Output folder is moved to Archive
When the function fails, the exception message I got was Access to path denied.
Thank you all for the replies and help. I have figured out what the issue was.
It is because there was a file that's not completely closed.
I was checking the files that were generated, and missed the files the program was reading from.
All files that were generated were closed completely. It was one file I used StreamReader to open but didn't close. I modified the code and am now not having problem, so I figure that's were the issue was.
Thanks for all the comments and answers, that definitely help me with thinking and figuring out the problem.
See http://windowsxp.mvps.org/processlock.htm
Sometimes, you try to move or delete a file or folder and receive access violation or file in use - errors. To successfully delete a file, you will need to identify the process which has locked the file. You need to exit the process first and then delete the particular file. To know which process has locked a file, you may use one of the methods discussed in this article.
Using Process Explorer - download from http://download.sysinternals.com/files/ProcessExplorer.zip
Process Explorer shows you information about which handles and DLLs processes have opened or loaded.
Download Process Explorer from Microsoft site and run the program.
Click the Find menu, and choose Find Handle or DLL...
Type the file name (name of the file which is locked by some process.)
After typing the search phrase, click the Search button
You should see the list of applications which are accessing the file.
I bumped on the same problem recently. Using PE I'd figured that only process using that particular directory was explorer.exe. I'd opened few windows with explorer, one pointing to parent directory of one that I was about to move.
It appeared, that after I visited that sub-folder and then returned (even to root level!) the handle was still being kept by explorer, so C# was not able to modify it in any way (changing flags, attributes etc.).
I had to kill that explorer window in order to made C# operate properly.
File.SetAttributes(Application.dataPath + "/script", FileAttributes.Normal);
Directory.Move(Application.dataPath + "/script", Application.dataPath + "/../script");
This fixed my problem.
Try this:
If this does not solve, maybe check/change the antivirus, or the some other program is locking some file in or the folder.
static object moveLocker = new object();
static void moveToArchive()
{
lock (moveLocker)
{
System.Threading.Thread.Sleep(2000); // Give sometime to ensure all file are closed.
//Environment.CurrentDirectory = System.AppDomain.CurrentDomain.BaseDirectory;
string applicationPath = System.AppDomain.CurrentDomain.BaseDirectory;
string archiveBaseDirectoryPath = System.IO.Path.Combine(applicationPath, "Archive");
if (!Directory.Exists(archiveBaseDirectoryPath)) Directory.CreateDirectory(archiveBaseDirectoryPath);
String timestamp = DateTime.Now.ToString("yyyyMMddHHmms");
String outputDirectory = System.IO.Path.Combine(Environment.CurrentDirectory, "Output");
String destinationTS = System.IO.Path.Combine(archiveBaseDirectoryPath, timestamp);
try
{
Directory.Move(outputDirectory, destinationTS);
}
catch (Exception ex)
{
Console.WriteLine("Can not move folder " + outputDirectory + " to: " + destinationTS + "\n" + ex.Message);
}
}
}
I had the same problem, it failed sometimes but not all the time. I thought I'd wrap it in a Try Catch block and present the user with an Access Denied message and once I wrapped it in the Try Catch block it stopped failing. I can't explain why.
If existingFile.FileName <> newFileName Then
Dim dir As New IO.DirectoryInfo(existingFile.FilePath)
Dim path As String = System.IO.Path.GetDirectoryName(dir.FullName)
newFileName = path & "\" & newFileName
File.SetAttributes(existingFile.FilePath, FileAttributes.Normal)
Try
IO.File.Move(existingFile.FilePath, newFileName)
Catch ex As Exception
End Try
End If
I had a similar problem. Renamed many directories in a loop when following the certain template. From time to time the program crashed on different directories. It helped to add a sleep thread before Directory.Move. I need to create some delay.
But it slows down the copying process.
foreach (var currentFullDirPath in Directory.GetDirectories(startTargetFullDirectory, "*", SearchOption.AllDirectories))
{
var shortCurrentFolderName = new DirectoryInfo(currentFullDirPath).Name.ToLower();
if (shortCurrentFolderName.Contains(shortSourceDirectoryName))
{
// Add Thread.Sleep(1000);
Thread.Sleep(1000);
var newFullDirName = ...;
Directory.Move(currentFullDirPath, newFullDirName);
}
}

System.UnauthorizedAccessException while creating a file

I was trying to write a code so that I could log the error messages. I am trying to name the file with the date and would like to create a new log file for each day. After going through a little look around, I came with the following code...
class ErrorLog
{
public void WriteErrorToFile(string error)
{
//http://msdn.microsoft.com/en-us/library/aa326721.aspx refer for more info
string fileName = DateTime.Now.ToString("dd-MM-yy", DateTimeFormatInfo.InvariantInfo);
//# symbol helps to ignore that escape sequence thing
string filePath = #"c:\users\MyName\mydocuments\visual studio 2012\projects\training\" +
#"discussionboard\ErrorLog\" + fileName + ".txt";
if (File.Exists(filePath))
{
// File.SetAttributes(filePath, FileAttributes.Normal);
File.WriteAllText(filePath, error);
}
else
{
Directory.CreateDirectory(filePath);
// File.SetAttributes(filePath, FileAttributes.Normal)
//Throws unauthorized access exception
RemoveReadOnlyAccess(filePath);
File.WriteAllText(filePath, error);
}
}
public static void RemoveReadOnlyAccess(string pathToFile)
{
FileInfo myFileInfo = new FileInfo(pathToFile);
myFileInfo.IsReadOnly = false;
myFileInfo.Refresh();
}
/*Exception thrown:
* UnAuthorizedAccessException was unhandled.
* Access to the path 'c:\users\anish\mydocuments\visual studio 2012\
* projects\training\discussionboard\ErrorLog\04\12\2013.txt' is denied.
*/
}
I found a forum that has discussed about a similar problem but using
File.SetAttrributes(filePath, FileAttributes.Normal) did not help neither did the RemoveReadOnlyAccess (included in the code above). When I check the properties of the folder, it has read only marked but even when I tick that off it comes back again. I checked the permissions on the folder and except for the special permission, which I was not able to change, everything is allowed.
Any suggestion on how I should proceed would be appreciated.
Why is access to the path denied? the link discusses about a similar problem, but I wasn't able to get my thing working with suggestions listed there.
Thanks for taking time to look at this.
Your path is strange : "My documents" directory must be "C:\Users\MyName\Documents\"
You can use Environment in order to correct it easily :
String myDocumentPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
Note that it will acces to "My documents" folder of the user that running your exe.
Second error, CreateDirectory must have a path in argument, not a file. using like you do will create a sub-directory with the file name. So you can't create a file with this name !
Try this :
String fileName = DateTime.Now.ToString("d", DateTimeFormatInfo.InvariantInfo);
String filePath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)
+ #"\visual studio 2012\projects\training\discussionboard\ErrorLog\";
String fileFullName = filePath + fileName + ".txt";
if (File.Exists(fileFullName ))
{
File.WriteAllText(fileFullName , error);
}
else
{
Directory.CreateDirectory(filePath);
[...]
}
}
Some possible reasons:
your app is not running under account which is allowed to access that path/file
the file is being locked for writing (or maybe reading too) by some other process
The first situation could be solved by checking under which account the process is running and verifying that the account has the appropriate rights.
The other situation can be solved by checking if any other process is locking the file (e.g. use tools like 'WhosLocking' or 'ProcessExplorer'
I had to run my app as an administrator in order to write to protected folders in c:. For example if debugging your app in visual studio make sure to right click on "C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.exe" and choose "Run As Administrator". Then open your solution from there. My app was trying to write to the root of c:\
Check your antivirus, it might be blocking the file creation.

Move a file from one directory to another

I created a zip file/folder with DotNetZip. I'm trying to move that file from the original directory/folder to another, e.g. My Documents. So far I have done the following, but it gives me an error saying that it could not find part of the path.
private static void Move()
{
try
{
Directory.Move(#"Debug\Settings.zip", IO.Paths.Enviroment.MyDocuments);
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
UPDATE:
So I've played with it a bit and laughed not because I fixed it but because it's weird. I used both File.Move() and Directory.Move() and changed both.Move(#"Debug\Settings.zip",...); to both.Move(#"Settings.zip",...); and then get get an an error saying Cannot create a file when that file already exists.
While it may seem strange to use Directory.Move to move a file, (I'd use File.Move instead), Jean-Philippe Leclerc points out that it will work.
The problem is with the path Debug\Settings.zip:
All relative paths are relative to the working directory. By default the working directory is the folder in which the assembly (your program) is executed, and while debugging that is the bin\Debug subfolder of your project. So your path Debug\Settings.zip is expanded to a path like:
C:\..\MyProject\bin\Debug\Debug\Settings.zip
This is probably not what you meant. You meant just "Settings.zip".
The fact that it's a ZIP is irrelevant.
Use System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) to get your MyDocuments path.
could not find part of the path - The error seems like the Relative Path to your file Settings.Zip is not a valid path!
You need to use File.Move, Directory.Move will move the entire content of the Directory to different folder.
File.Move : Only moves the file to a specified location
private static void Move()
{
try
{
File.Move(#"Debug\Settings.zip", System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
}
catch(Exception ex)
{
Console.WriteLine(ex.Message);
}
}
Fixed! The issues were first the "Debug\Settings.zip" should have been "Settings.zip" or #"Settings.zip" and finally destination should not just be System.IO.File.Move(#"Settings.zip", System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop)); but System.IO.File.Move(#"Settings.zip", System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop) + #"\Settings.zip"); Basically, add the file name and the extension of the file at the end of the destination string.

C# is writing a file in Visual Studio but not when I publish it

I have the following code which is supposed to go td on each of them through a list of orgs, call the toString method on each of them, and print the result to both the console and to a file named Debug1.tab.
try
{
StreamWriter print = File.CreateText("Debug1.tab");
Console.WriteLine(LinkedInClass.isThrottled);
int p = 1;
foreach (Org org in orgList)
{
try
{
if (org.numContacts > 0)
{
Console.WriteLine(org.ToString());
print.WriteLine(org.ToString());
}
}
catch (Exception) { Console.WriteLine(e.StackTrace); Console.WriteLine(e.Message); Console.ReadKey();}
}
print.Close();
Console.WriteLine("There were " + orgList.Count + " organizations in the list." + LinkedInClass.numWithContacts + " of which I found contacts for. Throttling was "+(LinkedInClass.isThrottled?"":"not ")+"encountered.");
break;
}
catch (Exception e) { Console.WriteLine(e.StackTrace); Console.WriteLine(e.Message); Console.ReadKey(); }
In Visual Studio it works perfectly but when I publish it the program doesn't create the file or write to it. It's still writing to the console, the catch statements aren't executing, and immediately after it should be closing the streamWriter it correctly prints to the console.
The way you specify the file name (without giving a path), the file is created in the current working directory, which may be different from the directory your application resides in. It may help to use the search your disk to see whether the file was created elsewhere.
Anyway: Specify a path when creating the file to make sure it's always in the location where you expect it to be (and do not use the Program Files folder, but some publically writable folder).
you should give full permission to your os curent user on the folder which you are going to write files to .To do that right click on the folder go to properties and go to securitty tab and add the curent user if It does not exist and provide full permission for that user .

Categories

Resources