Connecting Tech Pros Worldwide Forums | Help | Site Map

Check for file in use

Brian Simmons
Guest
 
Posts: n/a
#1: Aug 15 '07
Is there an easy way to check to see if a file is in use?

I want to open a CSV file from my .NET2 program, and write to it. However,
the file could be in use by another program. If that is the case, I don't
want to attempt to write to it, just abort.

Thanks,
Brian



Nicholas Paldino [.NET/C# MVP]
Guest
 
Posts: n/a
#2: Aug 15 '07

re: Check for file in use


Brian,

You could use the FileStream class and try to open the file with the
sharing/read/write options you need, and then catch the IOException (I
believe) that is thrown. However, an exception of this type can be thrown
for other conditions (like a disk error) and it's not clear (aside from the
message, which you can't reliably code against) from that exception what the
IO condition is.

Instead, what you can do is call the CreateFile API function through the
P/Invoke layer. If it returns a value of INVALID_HANDLE_VALUE, then you can
call the static GetLastWin32Error on the Marshal class and get the value
from GetLastError. This should correspond specifically to a value in
winerror.h which indicates that the file is currently in use.

--
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com

"Brian Simmons" <centraso@newsgroup.nospamwrote in message
news:%23zMoez03HHA.5160@TK2MSFTNGP05.phx.gbl...
Quote:
Is there an easy way to check to see if a file is in use?
>
I want to open a CSV file from my .NET2 program, and write to it.
However, the file could be in use by another program. If that is the
case, I don't want to attempt to write to it, just abort.
>
Thanks,
Brian
>

Vadym Stetsiak
Guest
 
Posts: n/a
#3: Aug 15 '07

re: Check for file in use


Hello, Brian!

Put the code that opens the file into try/catch(IOException) block. In the
catch
handle assume that file is in use. You can also check IOExceptio:HResult
property as it may contain
Win32 error number that corresponds to "File is in use by another process"

Also have a look at http://www.thescripts.com/forum/thread251072.html


You wrote on Wed, 15 Aug 2007 10:59:28 -0400:

BSI want to open a CSV file from my .NET2 program, and write to it.
BSHowever, the file could be in use by another program. If that is the
BScase, I don't want to attempt to write to it, just abort.


With best regards, Vadym Stetsiak.
Blog: http://vadmyst.blogspot.com


Nicholas Paldino [.NET/C# MVP]
Guest
 
Posts: n/a
#4: Aug 15 '07

re: Check for file in use


The OP can't check the HResult property because it is protected. The OP
would have to use reflection, which is a little bit too much overhead, IMO.


--
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com

"Vadym Stetsiak" <vadmyst@gmail.comwrote in message
news:u30g5903HHA.5776@TK2MSFTNGP04.phx.gbl...
Quote:
Hello, Brian!
>
Put the code that opens the file into try/catch(IOException) block. In the
catch
handle assume that file is in use. You can also check IOExceptio:HResult
property as it may contain
Win32 error number that corresponds to "File is in use by another process"
>
Also have a look at http://www.thescripts.com/forum/thread251072.html
>
>
You wrote on Wed, 15 Aug 2007 10:59:28 -0400:
>
BSI want to open a CSV file from my .NET2 program, and write to it.
BSHowever, the file could be in use by another program. If that is the
BScase, I don't want to attempt to write to it, just abort.
>
>
With best regards, Vadym Stetsiak.
Blog: http://vadmyst.blogspot.com
>

=?Utf-8?B?WWFyb24gS2Fybmk=?=
Guest
 
Posts: n/a
#5: Aug 15 '07

re: Check for file in use


Nicolas, good answer, when i look on this quiz, i think lets try to delete
it, in case of exception so, the file is being used.

A JOKE.
--
Sincerely
Yaron Karni
http://dotnetbible.blogspot.com/


"Nicholas Paldino [.NET/C# MVP]" wrote:
Quote:
Brian,
>
You could use the FileStream class and try to open the file with the
sharing/read/write options you need, and then catch the IOException (I
believe) that is thrown. However, an exception of this type can be thrown
for other conditions (like a disk error) and it's not clear (aside from the
message, which you can't reliably code against) from that exception what the
IO condition is.
>
Instead, what you can do is call the CreateFile API function through the
P/Invoke layer. If it returns a value of INVALID_HANDLE_VALUE, then you can
call the static GetLastWin32Error on the Marshal class and get the value
from GetLastError. This should correspond specifically to a value in
winerror.h which indicates that the file is currently in use.
>
--
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com
>
"Brian Simmons" <centraso@newsgroup.nospamwrote in message
news:%23zMoez03HHA.5160@TK2MSFTNGP05.phx.gbl...
Quote:
Is there an easy way to check to see if a file is in use?

I want to open a CSV file from my .NET2 program, and write to it.
However, the file could be in use by another program. If that is the
case, I don't want to attempt to write to it, just abort.

Thanks,
Brian
>
>
>
Peter Duniho
Guest
 
Posts: n/a
#6: Aug 15 '07

re: Check for file in use


Nicholas Paldino [.NET/C# MVP] wrote:
Quote:
The OP can't check the HResult property because it is protected. The OP
would have to use reflection, which is a little bit too much overhead, IMO.
And using p/invoke to call CreateFile directly isn't?

IMHO, the real answer is to just catch the exception and report it to
the user if it occurs. Yes, other exceptions could occur. But they
will have unique Message properties that can be displayed to the user,
and any exception needs to be dealt with, not just the one involving a
file that's already in use.

Yes, it's difficult for the code to do something conditionally based on
the exact error, but IMHO it's not necessary for the code to do that.
Any error that prevents the file from being opened is a problem.

Pete
Nicholas Paldino [.NET/C# MVP]
Guest
 
Posts: n/a
#7: Aug 15 '07

re: Check for file in use


"Peter Duniho" <NpOeStPeAdM@NnOwSlPiAnMk.comwrote in message
news:13c6elgrdi1rc7a@corp.supernews.com...
Quote:
Nicholas Paldino [.NET/C# MVP] wrote:
Quote:
> The OP can't check the HResult property because it is protected. The
>OP would have to use reflection, which is a little bit too much overhead,
>IMO.
>
And using p/invoke to call CreateFile directly isn't?
Obviously, IMO, it's not.
Quote:
IMHO, the real answer is to just catch the exception and report it to the
user if it occurs. Yes, other exceptions could occur. But they will have
unique Message properties that can be displayed to the user, and any
exception needs to be dealt with, not just the one involving a file that's
already in use.
I disagree here. The OP explicitly stated that they wanted to abort the
operation. Whether or not the OP wants it to abort silently, or not
silently was not specified.

If the OP wants the program to abort silently, then I would say just let
the exception fly and then wrap all the code in a try/catch statement, doing
nothing in the catch statement.

If the OP wants the program to not abort silently, then I whether or not
to propogate the exception would depend on how user-friendly the OP wants to
make his program. If the OP doesn't want something that is completely
user-friendly, then just let the exceptions fly.

However, if the does want something more user friendly message based on
a specific condition that can be checked for (in this case, is the file in
use), then working with IOException is not viable here, as it doesn't expose
the information in a way that can be easily ascertained.

The OP ^could^ use the suggestion to use the HResult property, but it
would require reflection, and at that point, you are basing the logic on an
implementation detail, which I think we would agree is a bad thing.

That leaves checking for the condition before trying to access the file,
which leaves the call to CreateFile.
Quote:
Yes, it's difficult for the code to do something conditionally based on
the exact error, but IMHO it's not necessary for the code to do that. Any
error that prevents the file from being opened is a problem.
Well, whether or not it's a problem, that's for the OP (and the users of
his program) to decide, really. If he could clarify it more, that would
help.

--
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com


Larry Smith
Guest
 
Posts: n/a
#8: Aug 15 '07

re: Check for file in use


There's always the remote possibility that the file won't be shared the
moment he checks it but will then be shared the moment he tries to open it
for (exclusive) writing. He therefore has to deal with the exception anyway.
Why waste the effort up front. I would personally consider a (reusable)
wrapper function that opens the file, catches the "IOException" and then
checks if it's really a sharing violation (which might also be gone by this
point so you can't entirely escape the problem - a "NumberOfRetries"
mechanism would usually solve thits however). If a sharing violation is
detected then simply throw a (custom) "SharingViolationException" with the
original "IOException" as its inner exception.


Nicholas Paldino [.NET/C# MVP]
Guest
 
Posts: n/a
#9: Aug 15 '07

re: Check for file in use


Larry,

That's the thing, how do you detect that the IOException actually occurs
as the result of the file being open? The two options are to use reflection
to get the HResult property which is protected and then check the error
code, or to parse the Message text, which is fragile at best (because of the
possibility of the Message property changing due to updates in the framework
and because of localization issues as well, as the Message property is more
than likely going to be localized). Neither is particularly stable, as they
both depend on implementation details.

Looking at the Marshal class, I realize that you could call the static
GetHRForException method to get the HRESULT code of the exception. This
HRESULT is the result of calling the HRESULT_FROM_WIN32 macro on the error
code ERROR_SHARING_VIOLATION (which has a value of 32):

http://msdn2.microsoft.com/en-us/library/ms680746.aspx

Looking in the code by calling the GetHRForException method, you can see
that the value 32 is definitely there (you have to convert to an unsigned
integer). Unfortunately, there is no definite way to map an HRESULT back to
a Win32 error code, as described here:

http://blogs.msdn.com/oldnewthing/ar...03/942851.aspx

I would say checking the IOException instance in this way is slightly
better, as you are still depending on an implementation detail (in the
conversion from the HRESULT to the Win32 error code). Granted, it's highly
unlikely that you are going to get an IOException which has an error code in
the HRESULT which is from a different facility or of a different severity,
so in the end, it's up to you what your poison is.

--
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com

"Larry Smith" <no_spam@_nospam.comwrote in message
news:%23zz%23M633HHA.1484@TK2MSFTNGP06.phx.gbl...
Quote:
There's always the remote possibility that the file won't be shared the
moment he checks it but will then be shared the moment he tries to open it
for (exclusive) writing. He therefore has to deal with the exception
anyway. Why waste the effort up front. I would personally consider a
(reusable) wrapper function that opens the file, catches the "IOException"
and then checks if it's really a sharing violation (which might also be
gone by this point so you can't entirely escape the problem - a
"NumberOfRetries" mechanism would usually solve thits however). If a
sharing violation is detected then simply throw a (custom)
"SharingViolationException" with the original "IOException" as its inner
exception.
>

Larry Smith
Guest
 
Posts: n/a
#10: Aug 16 '07

re: Check for file in use


That's the thing, how do you detect that the IOException actually
Quote:
occurs as the result of the file being open? The two options are to use
reflection to get the HResult property which is protected and then check
the error code, or to parse the Message text, which is fragile at best
(because of the possibility of the Message property changing due to
updates in the framework and because of localization issues as well, as
the Message property is more than likely going to be localized). Neither
is particularly stable, as they both depend on implementation details.
>
Looking at the Marshal class, I realize that you could call the static
GetHRForException method to get the HRESULT code of the exception. This
HRESULT is the result of calling the HRESULT_FROM_WIN32 macro on the error
code ERROR_SHARING_VIOLATION (which has a value of 32):
>
http://msdn2.microsoft.com/en-us/library/ms680746.aspx
>
Looking in the code by calling the GetHRForException method, you can
see that the value 32 is definitely there (you have to convert to an
unsigned integer). Unfortunately, there is no definite way to map an
HRESULT back to a Win32 error code, as described here:
>
http://blogs.msdn.com/oldnewthing/ar...03/942851.aspx
>
I would say checking the IOException instance in this way is slightly
better, as you are still depending on an implementation detail (in the
conversion from the HRESULT to the Win32 error code). Granted, it's
highly unlikely that you are going to get an IOException which has an
error code in the HRESULT which is from a different facility or of a
different severity, so in the end, it's up to you what your poison is.
In practice the situation doesn't normally require this level of precision.
If an "IOException" occurs and the equivalent Win32 function then indicates
a sharing violation only milliseconds later, you're pretty much guaranteed
that's what the problem is. The odds of the "IOException" being something
else are incredibly remote. Let's say it is however. Well there's still a
sharing violation at the Win32 level so reporting that is still accurate.
It's really (almost) as if you relied on Win32 directly in the first place
(for all intents and purposes). Since the course of action at this point for
most programs is to inform the user and/or log the error, you can simply
report something like:

Unable to open file "YourFile" due to a sharing violation. See application
event log for further details.

You can then clarify the situation in the log by dumping the original
"IOException" in addition to the sharing violation itself. While not a
perfect course of action theoretically, in reality it will work just fine.
In any case, I do agree with your HRESULT assessment. Not only is it an
implementation detail that you shouldn't rely on (since there's no guarantee
that ERROR_SHARING_VIOLATION will be propagated back), it seems implausible
to me that MSFT would ever recommend using "GetHRForException()" for this
purpose (mapping a standard .NET exception to a corresponding Win32 error -
in theory .NET has nothing to do with Win32).


Linda Liu [MSFT]
Guest
 
Posts: n/a
#11: Aug 16 '07

re: Check for file in use


Hi Brian,

When a .CSV file is opened by Excel or other programs except Notepad, it is
opened exclusively. We could make us of this feature to check if the file
is in use. That is, try to open this file to see if there's an exception.
If yes, this file is in use; otherwise, it's not in use.

The following is a sample.

public bool IsInUse(string filename)
{
try
{
System.IO.FileStream fs =
System.IO.File.OpenWrite(filename)
fs.Close();
return false;
}
catch (Exception exp)
{
return true;
}
}

Hope this helps.
If you have any question, please feel free to let me know.

Sincerely,
Linda Liu
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscripti...ult.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscripti...t/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.

GlennDoten
Guest
 
Posts: n/a
#12: Aug 16 '07

re: Check for file in use


Linda Liu [MSFT] wrote:
Quote:
Hi Brian,
>
When a .CSV file is opened by Excel or other programs except Notepad, it is
opened exclusively. We could make us of this feature to check if the file
is in use. That is, try to open this file to see if there's an exception.
If yes, this file is in use; otherwise, it's not in use.
>
The following is a sample.
>
public bool IsInUse(string filename)
{
try
{
System.IO.FileStream fs =
System.IO.File.OpenWrite(filename)
fs.Close();
return false;
}
catch (Exception exp)
{
return true;
}
}
>
Hope this helps.
If you have any question, please feel free to let me know.
Linda, how can you possibly assume that the only exception that may
occur in the code in the try block would be from a sharing violation?

Never, ever catch an Exception like that and ignore the actual value and
assume it will be what you think it will be. This code is a bug waiting
to happen, and an incredibly difficult one to track down.

Further, the Close call should be in a finally block. Or, better, the
FileStream instantiation should be within a using statement.

--
-glenn-
Nicholas Paldino [.NET/C# MVP]
Guest
 
Posts: n/a
#13: Aug 16 '07

re: Check for file in use


Additionally, the assumption that all other programs will open a CSV
file exclusively is incorrect as well.

--
- Nicholas Paldino [.NET/C# MVP]
- mvp@spam.guard.caspershouse.com

"GlennDoten" <gdoten@gmail.comwrote in message
news:ef79ij$3HHA.4400@TK2MSFTNGP06.phx.gbl...
Quote:
Linda Liu [MSFT] wrote:
Quote:
>Hi Brian,
>>
>When a .CSV file is opened by Excel or other programs except Notepad, it
>is opened exclusively. We could make us of this feature to check if the
>file is in use. That is, try to open this file to see if there's an
>exception. If yes, this file is in use; otherwise, it's not in use.
>>
>The following is a sample.
>>
>public bool IsInUse(string filename)
> {
> try
> {
> System.IO.FileStream fs =
>System.IO.File.OpenWrite(filename)
> fs.Close();
> return false;
> }
> catch (Exception exp)
> {
> return true;
> }
> }
>>
>Hope this helps.
>If you have any question, please feel free to let me know.
>
Linda, how can you possibly assume that the only exception that may occur
in the code in the try block would be from a sharing violation?
>
Never, ever catch an Exception like that and ignore the actual value and
assume it will be what you think it will be. This code is a bug waiting to
happen, and an incredibly difficult one to track down.
>
Further, the Close call should be in a finally block. Or, better, the
FileStream instantiation should be within a using statement.
>
--
-glenn-

GlennDoten
Guest
 
Posts: n/a
#14: Aug 17 '07

re: Check for file in use


[Re-posting under my MSDN email. Would really appreciate an answer.]

Date: Thu, 16 Aug 2007 07:30:43 -0400
From: GlennDoten <gdoten@gmail.com>
Subject: Re: Check for file in use
Newsgroups: microsoft.public.dotnet.languages.csharp

Linda Liu [MSFT] wrote:
Quote:
Hi Brian,
>
When a .CSV file is opened by Excel or other programs except Notepad,
it is
Quote:
opened exclusively. We could make us of this feature to check if the
file
Quote:
is in use. That is, try to open this file to see if there's an
exception.
Quote:
If yes, this file is in use; otherwise, it's not in use.
>
The following is a sample.
>
public bool IsInUse(string filename)
{
try
{
System.IO.FileStream fs =
System.IO.File.OpenWrite(filename)
fs.Close();
return false;
}
catch (Exception exp)
{
return true;
}
}
>
Hope this helps.
If you have any question, please feel free to let me know.
Linda, how can you possibly assume that the only exception that may
occur in the code in the try block would be from a sharing violation?

Never, ever catch an Exception like that and ignore the actual value and
assume it will be what you think it will be. This code is a bug waiting
to happen, and an incredibly difficult one to track down.

Further, the Close call should be in a finally block. Or, better, the
FileStream instantiation should be within a using statement.

--
-glenn-
Linda Liu [MSFT]
Guest
 
Posts: n/a
#15: Aug 21 '07

re: Check for file in use


Hi Glenn,

Thank you for pointing out the problem within my sample code!

Sincerely,
Linda Liu
Microsoft Online Community Support

Linda Liu [MSFT]
Guest
 
Posts: n/a
#16: Aug 21 '07

re: Check for file in use


Hi Brian,

How about the problem now?

If you need our further assistance, please feel free to let us know.

Thank you for using our MSDN Managed Newsgroup Support Service!

Sincerely,
Linda Liu
Microsoft Online Community Support

Closed Thread


Similar C# / C Sharp bytes