I need create a file and need to write the every exception in a file. i am using bellow code to do that.
File.Create(filePath);
File.AppendText("Exception Detail Start-------------------------------------------");
File.AppendText("Stack Trace :" + ex.StackTrace );
File.AppendText("Error :" + ex.Message );
File.AppendText("Exception Detail End-------------------------------------------");
But I'm getting the below error:
Additional information: Access to the path 'C:\Program Files (x86)\IIS Express\Exception Detail Start-------------------------------------------' is denied`
File.AppendText takes a file path and returns a StreamWriter. So in your case you are passing the exception message as the file path, and hence the file is not found (it is looking file a file in the current directory named "Exception Detail Start-------------------------------------------").
In your case you might want to use File.AppendAllText.
Opens a file, appends the specified string to the file, and then
closes the file. If the file does not exist, this method creates a
file, writes the specified string to the file, then closes the file.
Or File.AppendAllLines.
Appends lines to a file, and then closes the file. If the specified
file does not exist, this method creates a file, writes the specified
lines to the file, and then closes the file.
Example:
File.AppendAllLines(filePath, new string[] {
"Exception Detail Start-------------------------------------------",
"Stack Trace :" + ex.StackTrace,
"Error :" + ex.Message,
"Exception Detail End-------------------------------------------"
});
You don't write to the file you created.
FileStream writer = File.Create(filePath);
writer.AppendText("Exception Detail Start-------------------------------------------");
writer.AppendText("Stack Trace :" + ex.StackTrace );
writer.AppendText("Error :" + ex.Message );
writer.AppendText("Exception Detail End-------------------------------------------");
This should work.
Your C\program files (x86) path usually requires administrative right to write files. Try starting your application as administrator. (Alternatively start visual studio as administrator and run your project)
If it successfully writes to the file when run as administrator maybe consider choosing a folder that requires no administrative priviledges or add priviledges to a chosen folder for your program.
Related
We have a process where people scan documents with photocopiers and drop them in a certain directory on our file server. We then have a hourly service within an .NET Core app, that scans the directory, grabs the file and moves them according to their file name to a certain directory. Here comes the problems.
The code looks something like that:
private string MoveFile(string file, string commNumber)
{
var fileName = Path.GetFileName(file);
var baseFileName = Path.GetFileNameWithoutExtension(fileName).Split("-v")[0];
// 1. Check if the file already exists at destination
var existingFileList = luxWebSamContext.Documents.Where(x => EF.Functions.Like(x.DocumentName, "%" + Path.GetFileNameWithoutExtension(baseFileName) + "%")).ToList();
// If the file exists, check for the current version of file
if (existingFileList.Count > 0)
{
var nextVersion = existingFileList.Max(x => x.UploadVersion) + 1;
var extension = Path.GetExtension(fileName);
fileName = baseFileName + "-v" + nextVersion.ToString() + extension;
}
var from = #file;
var to = Path.Combine(#destinationPath, commNumber,fileName);
try
{
log.Info($"------ Moving File! ------ {fileName}");
Directory.CreateDirectory(Path.Combine(#destinationPath, commNumber));
File.Move(from, to, true);
return to;
}
catch (Exception ex)
{
log.Error($"----- Couldn't MOVE FILE: {file} ----- commission number: {commNumber}", ex);
The interesting part is in the try-block, where the file move takes place. Sometmes we have the problem that the program throws the following exception
2021-11-23 17:15:37,960 [60] ERROR App ----- Couldn't MOVE FILE:
\PATH\PATH\PATH\Filename_423489120.pdf ----- commission number:
05847894
System.IO.IOException: The process cannot access the file because it is being used by another process.
at System.IO.FileSystem.MoveFile(String sourceFullPath, String destFullPath, Boolean overwrite)
at System.IO.File.Move(String sourceFileName, String destFileName, Boolean overwrite)
So far so good. I would expect that after the file cannot be moved, it remains in the directory from it was supposed to be moved. But that's not the case. We had this issue yesterday afternoon and after I looked for the file, it was gone from the directory.
Is this the normal behaviour of the File.Move() method?
First to your question:
Is this the normal behaviour of the File.Move() method?
No, thats not the expected behaviour. The documentation says:
Moving the file across disk volumes is equivalent to copying the file
and deleting it from the source if the copying was successful.
If you try to move a file across disk volumes and that file is in use,
the file is copied to the destination, but it is not deleted from the
source.
Your Exception says, that another process is using the file in the same moment. So you should check, whether other parts of your application may performs a Delete, or someone (if this scenario is valid) is deleting files manually from the file system.
Typically, File.Move() only removes the source file, once the destination file is successfully transferred in place. So the answer to your question is no, it cannot be purely the File.Move(). The interesting part is, why is this file locked? Probaby because some file stream is still open and blocking access to the file. Also, do you have multiple instances of the copy process services running? This may cause several services trying to access the file simultaneously, causing the exception you posted.
There must be a different cause making the files disappear because the File.Move() will certainly not remove the file when the copy process did not succeed.
For debugging purposes, you may try and open the file with a lock on it. This will fail when a different process locks the file providing you a little bit more information.
file.CopyTo(destinationFullName , true);
if (destinationFullName == file.FullName) {
logTrace(TraceEventType.Information, "Overwritten file " + file.FullName + " with " + destinationFullName);
}
Is there a good way to detect if a file is being overwritten instead of manually comparing file name of source and destination. I was like to log a message if CopyTo overwrites a file.
If you don't want to check if the file exists before you try to copy, you could use the File.Copy() method where it says right in the documentation that overwriting a file is not allowed:
Copies an existing file to a new file. Overwriting a file of the same name is not allowed.
...
IOException
destFileName exists.
So you could put the Copy in a try, and then catch an IOException that would indicate that the file already exists. See the link I pasted for more information.
I am sure you have a good reason for not wanting to check for the existence of the file in advance. I don't normally recommend using a try catch block like this though.
I'm creating an app for Windows in C# that extracts .zip file into the %temp% folder and shows you the contents and lets you edit them. After you finish editing the files, you can save the file again - the app deletes the original .zip and compresses the folder into the same file (that was deleted) so that it looks like it was replaced.
I've tried creating a new empty .zip file through the app and saving it. That worked. Then I also tried creating a folder in it and saving it. That also worked, but when I create a new .txt file, then it gives me the "file in use" error. This error doesn't occur when I edit a .txt file that already was in the .zip archive and save it.
//.txt file creation into the dir where the .zip file was extracted
System.IO.File.Create(System.IO.Path.GetTempPath() + "UltraDocs\\" + rnd + "\\" + listBox1.GetItemText(listBox1.SelectedItem) + "\\" + toolStripTextBox3.Text + ".txt");
System.IO.File.SetAttributes(System.IO.Path.GetTempPath() + "UltraDocs\\" + rnd + "\\" + listBox1.GetItemText(listBox1.SelectedItem) + "\\" + toolStripTextBox3.Text + ".txt", ~System.IO.FileAttributes.ReadOnly);
//Compression
System.IO.File.Delete(filedia.FileName);
ZipFile.CreateFromDirectory(System.IO.Path.GetTempPath() + "UltraDocs\\" + rnd, filedia.FileName);
//This line gives me a "*.txt is currently in use by another process" error
Any ideas what might be causing this error and how to fix it?
I'm trying to write a small console app tool that unzips an archive containing multiple files/folders/other archives and arrange it's contents in another way.
I unzip the root file with ZipFile.ExtractToDirectory method from System.IO.Compression.FileSystem library:
public static void UnzipPackage(string packagePath, string targetPath)
{
try
{
ZipFile.ExtractToDirectory(packagePath, targetLocation);
Console.WriteLine("Unzipping file {0} complete.", packagePath);
}
catch (DirectoryNotFoundException)
{
Console.WriteLine("Directory was not found.");
}
catch (FileNotFoundException)
{
Console.WriteLine("File was not found.");
}
}
After running this method on my package, I want to copy a file which was in this package in a subfolder.
According to MSDN I do this:
if (!Directory.Exists(targetLocation + #"READY\PHOTO"))
{
Directory.CreateDirectory(targetLocation + #"\READY\PHOTO");
}
if (Directory.Exists(targetLocation + #"\MAIN\PHOTO"))
{
string[] files = Directory.GetFiles(targetLocation + #"\MAIN\PHOTO");
foreach (var file in files)
{
string fileName = Path.GetFileName(file);
string destFile = Path.Combine(targetLocation + #"\MAIN\PHOTO", fileName);
File.Copy(file, destFile, true);
}
}
Both MAIN and READY are my subdirectories where whole package goes ("main") and sorted files go ("ready").
However, when running this, the zip file is not yet unzipped - an exception occurs showing it can't access the file specified even though it grabbed it's name from Directory.GetFiles(). The folder created when unzipping the zip file shows only after I terminate my console app (no wonder it can't access it).
So the big question is - how can I wait for the unzipped folder to show up? I tried using Thread.Sleep(), but it doesn't affect the flow anyhow - an exception still occurs, and the folder shows only after I terminate the app.
Your error is here:
string destFile = Path.Combine(targetLocation + #"\MAIN\PHOTO", fileName);
Should be:
string destFile = Path.Combine(targetLocation + #"\READY\PHOTO", fileName);
You're attempting to copy the file to the same location.
I'm assuming your getting an IOException something like "The process cannot access the file...because it is being used by another process."
It looks to me that there is a problem in your copy method. It looks like your from and to paths are essentially the same. So the system cannot overwrite the file, because you currently have it open for reading.
Just to be clear - the issue is not related to unzipping! In the example you have written the variable file and destFile are going to be the same - and they need to be different.
When trying to extract a .jar file, I keep getting:
Extracting an archive entry would create a file that is outside the specified destination directory
Can anyone help me? Here is my code:
try
{
using (ZipArchive archive = ZipFile.Open(jarLocationTXT.Text, ZipArchiveMode.Update))
{
archive.ExtractToDirectory(#"C:\Users\Neglekt\Monix Software\MCMI\CurExtract\");
}
}
catch (IOException ExtrEx)
{
MessageBox.Show(ExtrEx.ToString());
MessageBox.Show("An error occured while processing your data! \n Error code: E:002", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
The documentation says an exception like that is thrown when:
For example, the entry name contains parent directory accessors.
A parent directory accesor is for example ... When you are at the command prompt and you type cd .., you are telling the change directory (cd) program to go to the parent directory, that's what .. means. So the exception is thrown because an entry in the zip file contains that a reference to some parent directory.
It doesn't seem like there is a way to bypass that check when using the ExtractToDirectory, so an option would be to roll your own extraction method, either with a static or an extension method. What I mean by that is creating a method of your own that:
Takes the path to the zip file and destination directory
Opens the file in a ZipArchive.
Iterates through its Entries
Extracts each ZipArchiveEntry to a file using the destination directory provided and the relative path from the entry.