views:

1116

answers:

4

Here's the deal.

My WinApp is running, right? in let's say process 'A'.It creates a file and keeps the handle (keeps the file open for writing, this is a must).
Then it starts other msbuild process, let's call it 'B'. This process is started with the System.Diagnostic.Process class.
At some point, my WinApp (A) needs to delete the previously created file (remember it was created by A itself), and that's when I get an IOException with the message "The process cannot access the file 'X' because it is being used by another process". And it actually is!... If I terminate process 'B', only then 'A' can successfully delete the file.

So my questions are:
1) Is there a way I can tell the process I create not no handle the files I opened?
2) Is there another way to achieve my scenario?

A: 

It is possible to force a file handle closed without closing the process is using the handle, though this might cause the application to crash. In other words, doing what you wannt to do may cause 'B' to crash. That said, what you are asking for is definitely possible, since the application, Process Explorer can do this. I you search the messageboard in that link, you might find it informative, though even the act of finding which application is using a handle is an exercise in frustration, never mind actually closing the handle.

Brian
A: 

I don't know of a guaranteed way to delete a file with open handles, but if you can wait until a system restart for the file to be deleted, you can use the same technique as the MoveFile utility from Sysinternals.

This program adds registry values to the HKLM\System\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations key which Windows checks on boot, and this will guarantee the file gets deleted, albeit not immediately.

Bork Blatt
+2  A: 

It looks like System.Diagnostic.Process.Start calls CreateProcess with the bInheritHandles argument set to true.

You could try setting UseShellExecute to true in ProcessStartInfo, or directly P/Invoke to CreateProcess.

Arnout
I really like this suggestion, but unfortunately is not working... I have no idea why B is keeping the handle of the file created by A
sebastian
Actually, I need UseShellExecute set to false in order to redirect my output... I guess it's not possible to do that from the .net framework standard classes.
sebastian
B is "keeping" the handle of A's file because that handle was inherited due to the way CreateProcess was called. You could take a peek at System.Diagnostics.Process (or use the framework source code) to get an idea of what's involved to P/Invoke to CreateProcess yourself.
Arnout
A: 

I had come across a similar problem when I was trying to read a file that was exclusively locked.

I was trying to do it using :

FileStream exclusiveWriter = new FileStream(@"C:\Temp\FileLockTest1.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);

The complete discussion is available at :

File exclusively locked by another process - MSDN Forum disucssion

Hope this helps.

Codex