.NET File locking problem - c#

I am currently doing the following:
I create a file using FileStream braced in the using() tag - Only the file creation takes place within the using statement. The rest of the statements are nearly sequential.
Launch the file I have created using Process.Start()
Read a small bit of meta data from the file using Assembly.ReflectionOnlyLoadFrom()
List the running processes using Process.GetProcessesByName
Kill the Process using Process.Kill
Try to delete the file using File.Delete()
My problem is that my application is locking the file, so when I try to delete it, nothing happens. It throws an exception saying "Access is Denied" if I try to delete, and throws "Another process is using this file" if I try to write to it.
What on earth could be consuming the file from the above (literally all there is)? I have set all references to null, and gone as far as to call the dreaded GC.Collect() and no luck.

When you load assembly it's hosted in the current AppDomain. If you load it using ReflectionOnlyLoad(byte[]) it will load it as shadow and won't lock the file.
var bytes = File.ReadAllBytes(path);
var assembly = Assembly.ReflectionOnlyLoad(bytes);
Currently, the code that blocks the file is Assembly.ReflectionOnlyLoadFrom() and not the writing to the file (assuming the FileStream is disposed before trying to delete). The file will be released only when the AppDomain is unloaded.

Clearly, you are doing something in your code that causes the assembly to be loaded in your own process. Once there, it is stuck and the file is locked until the AppDomain in which it gets loaded gets unloaded. Which is no doubt the primary one, it's stuck until your program terminates.
Pay attention to the Visual Studio Output window, you'll get a debugger notification as soon as it gets loaded. Stepping through your code while watching that window will easily isolate the statement that causes it.

You can do an analysis with the Process Monitor tool. It can capture the call stack of each file access thus should be sufficient to tell you where/when the file is locked.

Related

Any possibility to find out unclosed streams in C# code?

I am busy writing an additional module to an existing C# application. In my module I have to generate some data and add it to ZIP archives created by the main program. (Ionic.Zip library is used). In most cases I can successfully update existing archives and store them again. But sometimes (and quite often) this does not work, since, as far as I understand, something in the main program opens a stream to the concerned archive file and fails to close it before I try to access it.
It is absolutely clear that the process that locks the files is the main program itself (tested with a tool based on How do I find out which process is locking a file using .NET?).
I am not aware of any technical possibility to trace down the point in the code where a file is opened without being (somewhere) closed, but it is my hope that such a technique may exist however and that someone could share some information on it.
TIA

File.ReadAllBytes keeps file handle open

I have this piece of code, which loads a file into RAM, then loads it as an assembly into an AppDomain (d):
var a = d.Load(File.ReadAllBytes(tmp));
The problem is that when I later try to delete the file located at tmp (right now just using File Explorer), I get an error saying that the file is still open in my program. I even tried using the using keyword with File.Open, and that didn't seem to work either. Can someone please explain why this might be happening, and how to fix it?
ReadAllBytes is supposed to close the file as part of its function. It sounds like something is preventing it from closing, and therefore you cannot delete. Maybe there's an exception happening that needs to be caught.
Here is a similar question with a solution which may be helpful:
Unable to delete some files via System.IO.File in C# console app

FileStream.close() does not free file for other processes

I have Following Code in a Page_Load called function. When the Page is loaded the first time after starting Visual Studio, everything works out fine.
But any other opening call to the File after that returns IOException: "File is in use by another process", even when directly opening the File in VisualStudio Solution this Error is returned(of course not as Exception)
FileStream mailinglist_FileStream = new FileStream(#"\foobarFile.txt", FileMode.Open);
PeekingStreamReader mailinglist_Reader = new PeekingStreamReader(mailinglist_FileStream);
//Do some stuff with the file
mailinglist_FileStream.Close();
mailinglist_Reader.Close();
mailinglist_Reader.Dispose();
mailinglist_FileStream.Dispose();
Why is the file still locked? and why does fully restarting Visual Studio reset the File?
when checking file-Properties it says:
Build Action: Content
Copy to output directory: do not Copy
I am only reading this File. can i do something similiar to adLockOptimistic, so that multiple processes can access the File?
Why is the file still locked? and why does fully restarting Visual
Studio reset the File? when checking file-Properties it says [...]
I don't know why the file is still locked: probably because your code fails before the stream is closed/disposed.
About "why fully restarting Visual Studio [...]": because you may be using IIS Express or ASP.NET Dev Server whose are closed when you close the IDE, so locks on files are released since the process holding the locks is no longer running.
And about "why is the file still locked?[...]" it could be because the file stream isn't closed because sometimes the thread may not end successfully and the locks aren't released.
As other answer said, check how using block may avoid that IDisposable objects wouldn't be disposed:
// FileShare.ReadWrite will allow other processes
// to read and write the target file even if other processes
// are working with the same file
using var mailinglist_FileStream = new FileStream(#"\foobarFile.txt", FileMode.Open, FileShare.ReadWrite);
using var mailinglist_Reader = new PeekingStreamReader(mailinglist_FileStream);
// Do your stuff. Using blocks will call Dispose() for
// you even if something goes wrong, as it's equal to a try/finally!
I am only reading this File. can i do something similiar to
adLockOptimistic, so that multiple processes can access the File?
Yes, take a look at File.Open method and FileShare enumeration:
File.Open: http://msdn.microsoft.com/en-us/library/y973b725.aspx
FileShare enum: http://msdn.microsoft.com/en-us/library/system.io.fileshare.aspx
Learn to use using:
using (FileStream fileStream = File.Open(#"C:\somefile", FileMode.Open, FileAccess.Read))
{
...
}
The using construct ensures that the file will be closed when you leave the block even if an exception is thrown.
Your problem might not be here, but somewhere else in your code. You'll have to go through all your code and look for places where you have opened files but not put it inside a using statement.
An old question but unfortunately the given answers can be not applicable to the question.
The problem specifically in Windows lies in two aspects of Windows behavior:
a) when the handle to the file, opened for writing, is closed, the Microsoft Antimalware Service opens the file to check the newly written data for malware;
b) the OS itself keeps the file opened for some time after all handles to it are closed. This time can be from seconds to many minutes depending on the nature of the file and other factors.
We saw this problem many times in our products and had to provide special support for this case - our kernel-mode attempts to close the file as soon as the last handle to it is closed.
Try using using blocks, it may not fix your lock problem, but it is better form for disposable objects.
using (FileStream mailinglist_FileStream = new FileStream(#"\foobarFile.txt", FileMode.Open))
{
using (PeekingStreamReader mailinglist_Reader = new PeekingStreamReader(mailinglist_FileStream))
{
...
}
}
Also, try closing mailinglist_Reader before mailinglist_FileStream.

How to wait for a file to be copied completely?

I have a thread which polls a folder for new files. The problem is that it sees a new file and starts working on it even before the file has been completely copied by another process. Because of this the poller gets file used by another process error.
Is there a way to check the file is free to use or get notified? We can certainly use exception handling code, but is there a better way?
Tech: .NET 2.0/C#
Update:
Found out from other answers that if we have access to the app writing the file then better design is to start with some other extension .tmp and then rename it after copying.
The FileStream.Lock could be used if we don't control the source application
We attempt to get a lock on the file before processing it and handle the IOException rather than a generic exception during the attempt to read the file.
See FileStream.Lock on MSDN.

Removing file locks

I need to recover form an error case where a file gets left in a locked state. How can I in c# tell this file to reset it's locks? I need to add to this the file is opened by a 3rd party dll and I don't actually have access to the file handle.
Locking a file is the responsibility of the Operating System (on behalf of the program that opens it). If a file is left in a locked state, its really up to the OS to unlock. This typically happens automatically when the process that opened the file exits.
There is, however, a really cool utility that I came across that will help. It's called Unlocker.
You could perhaps start a command line process like net or psfile with something along the lines of:
System.Diagnostics.Process.Start("psfile c:\myfile.txt -c");
You can get psfile here.
You could also use
net file ID /close
but that would require you to know the file ID, which would take a bit more work.
Untested but this should give you a starting point.
I would really consider finding another 3rd party dll. Any system handling Streams should properly respond to error conditions and not leave things like file locks in place.
Is it possible that the library does provide error condition clean up, you've just over looked it? Try something like the following,
try {
thirdPartyObj = new ThirdPartObj();
// Some possible error causing object actions
catch(Exception ex) {
thirdPartyObj = null; // The object should close its resources
}
You have to close the file using .Close(). You need to make sure you still have a way of accessing the file object.
You usually can avoid this error by writing a try{} ... finally {} construct after the code that does your file I/O. In the finally {} block, you'd call the Close method of your file object, preventing this condition. You can also use a using {} block when you create your files, and this will also take care of this problem.

Categories

Resources