Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2008/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 是否有一种编程方式来确定文件是否正在使用?_C#_Visual Studio 2008_File_Interop - Fatal编程技术网

C# 是否有一种编程方式来确定文件是否正在使用?

C# 是否有一种编程方式来确定文件是否正在使用?,c#,visual-studio-2008,file,interop,C#,Visual Studio 2008,File,Interop,案例和要点:我需要通过Interop打开一个Excel文件,如果我知道该文件正在使用,这将有助于避免糟糕的COM错误 除了尝试打开文件并捕获异常外,是否有一种编程方式来确定文件是否正在使用?您需要使用Win32 API fileopen(CreateFile或lopen)进行独占访问并检查返回值。无论您使用什么方法,在调用和实际打开文件之间,没有任何东西可以证明另一个进程没有打开文件 一些伪代码: internal File OpenExcelFile(String fileName) {

案例和要点:我需要通过Interop打开一个Excel文件,如果我知道该文件正在使用,这将有助于避免糟糕的COM错误


除了尝试打开文件并捕获异常外,是否有一种编程方式来确定文件是否正在使用?

您需要使用Win32 API fileopen(CreateFile或lopen)进行独占访问并检查返回值。

无论您使用什么方法,在调用和实际打开文件之间,没有任何东西可以证明另一个进程没有打开文件

一些伪代码:

internal File OpenExcelFile(String fileName)
{
    File file = null;
    var fileOpened = SomeLibrary.IsFileOpened(fileName);

    if (!fileOpened)
    {
       // Nothing garanties that another process didnt grabbed the file between call and that the file is still closed!!!
       file = ExcelLibrary.OpenFile(fileName);
    }

    return file;
}

那就更糟了。您不仅需要捕获异常,还必须使用反射来消除它与其他错误之间的歧义。至少,这是我找到的唯一解决办法

        try
        {
            using (StreamWriter sw = new StreamWriter(filepath, false))
            {
                sw.Write(contents);
            }
        }
        catch (System.IO.IOException exception)
        {
            if (!FileUtil.IsExceptionSharingViolation(exception))
                throw;
        }


我想知道处理Win32错误代码的开销是否会抵消不使用try/catch方法的好处?
    public static bool IsExceptionSharingViolation(IOException exception)
    {
        Type type = typeof(Exception);

        PropertyInfo pinfo = type.GetProperty("HResult", BindingFlags.NonPublic | BindingFlags.Instance);

        uint hresult = (uint)(int)pinfo.GetValue(exception, null);

        //ERROR_SHARING_VIOLATION = 32
        //being an HRESULT adds the 0x8007

        return hresult == 0x80070020;
    }