How to check for file lock? [duplicate]

2018-12-31 07:25发布

This question already has an answer here:

Is there any way to check whether a file is locked without using a try/catch block?

Right now, the only way I know of is to just open the file and catch any System.IO.IOException.

12条回答
人间绝色
2楼-- · 2018-12-31 07:34

Same thing but in Powershell

function Test-FileOpen
{
    Param
    ([string]$FileToOpen)
    try
    {
        $openFile =([system.io.file]::Open($FileToOpen,[system.io.filemode]::Open))
        $open =$true
        $openFile.close()
    }
    catch
    {
        $open = $false
    }
    $open
}
查看更多
呛了眼睛熬了心
3楼-- · 2018-12-31 07:44

Then between the two lines, another process could easily lock the file, giving you the same problem you were trying to avoid to begin with: exceptions.

However, this way, you would know that the problem is temporary, and to retry later. (E.g., you could write a thread that, if encountering a lock while trying to write, keeps retrying until the lock is gone.)

The IOException, on the other hand, is not by itself specific enough that locking is the cause of the IO failure. There could be reasons that aren't temporary.

查看更多
回忆,回不去的记忆
4楼-- · 2018-12-31 07:48

Instead of using interop you can use the .NET FileStream class methods Lock and Unlock:

FileStream.Lock http://msdn.microsoft.com/en-us/library/system.io.filestream.lock.aspx

FileStream.Unlock http://msdn.microsoft.com/en-us/library/system.io.filestream.unlock.aspx

查看更多
零度萤火
5楼-- · 2018-12-31 07:49

You can see if the file is locked by trying to read or lock it yourself first.

Please see my answer here for more information.

查看更多
余生无你
6楼-- · 2018-12-31 07:51

When I faced with a similar problem, I finished with the following code:

public bool IsFileLocked(string filePath)
{
    try
    {
        using (File.Open(filePath, FileMode.Open)){}
    }
    catch (IOException e)
    {
        var errorCode = Marshal.GetHRForException(e) & ((1 << 16) - 1);

        return errorCode == 32 || errorCode == 33;
    }

    return false;
}
查看更多
泪湿衣
7楼-- · 2018-12-31 07:52

You can also check if any process is using this file and show a list of programs you must close to continue like an installer does.

public static string GetFileProcessName(string filePath)
{
    Process[] procs = Process.GetProcesses();
    string fileName = Path.GetFileName(filePath);

    foreach (Process proc in procs)
    {
        if (proc.MainWindowHandle != new IntPtr(0) && !proc.HasExited)
        {
            ProcessModule[] arr = new ProcessModule[proc.Modules.Count];

            foreach (ProcessModule pm in proc.Modules)
            {
                if (pm.ModuleName == fileName)
                    return proc.ProcessName;
            }
        }
    }

    return null;
}
查看更多
登录 后发表回答