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

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

[{'answer_id': 1309, 'author': 'Lasse V. Karlsen', 'author_id': 267, 'author_profile': 'https://Stackoverflow.com/users/267', 'pm_score': 8, 'selected': True, 'text': '<p>No, unfortunately, and if you think about it, that information would be worthless anyway since the file could become locked the very next second (read: short timespan).</p>\n\n<p>Why specifically do you need to know if the file is locked anyway? Knowing that might give us some other way of giving you good advice.</p>\n\n<p>If your code would look like this:</p>\n\n<pre><code>if not locked then\n    open and update file\n</code></pre>\n\n<p>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.</p>\n'}, {'answer_id': 13789, 'author': 'Sören Kuklau', 'author_id': 1600, 'author_profile': 'https://Stackoverflow.com/users/1600', 'pm_score': 2, 'selected': False, 'text': "<blockquote>\n  <p>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.</p>\n</blockquote>\n\n<p>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.)</p>\n\n<p>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.</p>\n"}, {'answer_id': 626095, 'author': 'Brian R. Bondy', 'author_id': 3153, 'author_profile': 'https://Stackoverflow.com/users/3153', 'pm_score': 2, 'selected': False, 'text': '<p>You can see if the file is locked by trying to read or lock it yourself first. </p>\n\n<p><a href="https://stackoverflow.com/questions/203837/can-i-simply-read-a-file-that-is-in-use/203839#203839">Please see my answer here for more information</a>.</p>\n'}, {'answer_id': 1176082, 'author': 'Sam Saffron', 'author_id': 17174, 'author_profile': 'https://Stackoverflow.com/users/17174', 'pm_score': 3, 'selected': False, 'text': '<p>You could call <a href="http://msdn.microsoft.com/en-us/library/aa365202%28VS.85%29.aspx" rel="nofollow noreferrer">LockFile</a> via interop on the region of file you are interested in. This will not throw an exception, if it succeeds you will have a lock on that portion of the file (which is held by your process), that lock will be held until you call <a href="http://msdn.microsoft.com/en-us/library/aa365715%28VS.85%29.aspx" rel="nofollow noreferrer">UnlockFile</a> or your process dies. </p>\n'}, {'answer_id': 2403108, 'author': 'Sergio Vicente', 'author_id': 198152, 'author_profile': 'https://Stackoverflow.com/users/198152', 'pm_score': 4, 'selected': False, 'text': '<p>Instead of using interop you can use the .NET FileStream class methods Lock and Unlock:</p>\n\n<p>FileStream.Lock\n<a href="http://msdn.microsoft.com/en-us/library/system.io.filestream.lock.aspx" rel="noreferrer">http://msdn.microsoft.com/en-us/library/system.io.filestream.lock.aspx</a></p>\n\n<p>FileStream.Unlock\n<a href="http://msdn.microsoft.com/en-us/library/system.io.filestream.unlock.aspx" rel="noreferrer">http://msdn.microsoft.com/en-us/library/system.io.filestream.unlock.aspx</a></p>\n'}, {'answer_id': 3202085, 'author': 'DixonD', 'author_id': 213725, 'author_profile': 'https://Stackoverflow.com/users/213725', 'pm_score': 8, 'selected': False, 'text': '<p>When I faced with a similar problem, I finished with the following code:</p>\n<pre><code>public class FileManager\n{\n    private string _fileName;\n\n    private int _numberOfTries;\n\n    private int _timeIntervalBetweenTries;\n\n    private FileStream GetStream(FileAccess fileAccess)\n    {\n        var tries = 0;\n        while (true)\n        {\n            try\n            {\n                return File.Open(_fileName, FileMode.Open, fileAccess, Fileshare.None); \n            }\n            catch (IOException e)\n            {\n                if (!IsFileLocked(e))\n                    throw;\n                if (++tries &gt; _numberOfTries)\n                    throw new MyCustomException(&quot;The file is locked too long: &quot; + e.Message, e);\n                Thread.Sleep(_timeIntervalBetweenTries);\n            }\n        }\n    }\n\n    private static bool IsFileLocked(IOException exception)\n    {\n        int errorCode = Marshal.GetHRForException(exception) &amp; ((1 &lt;&lt; 16) - 1);\n        return errorCode == 32 || errorCode == 33;\n    }\n\n    // other code\n\n}\n</code></pre>\n'}, {'answer_id': 5512640, 'author': 'Aralmo', 'author_id': 687466, 'author_profile': 'https://Stackoverflow.com/users/687466', 'pm_score': 4, 'selected': False, 'text': '<p>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.</p>\n\n<pre><code>public static string GetFileProcessName(string filePath)\n{\n    Process[] procs = Process.GetProcesses();\n    string fileName = Path.GetFileName(filePath);\n\n    foreach (Process proc in procs)\n    {\n        if (proc.MainWindowHandle != new IntPtr(0) &amp;&amp; !proc.HasExited)\n        {\n            ProcessModule[] arr = new ProcessModule[proc.Modules.Count];\n\n            foreach (ProcessModule pm in proc.Modules)\n            {\n                if (pm.ModuleName == fileName)\n                    return proc.ProcessName;\n            }\n        }\n    }\n\n    return null;\n}\n</code></pre>\n'}, {'answer_id': 14132721, 'author': 'Tristan', 'author_id': 642282, 'author_profile': 'https://Stackoverflow.com/users/642282', 'pm_score': 3, 'selected': False, 'text': "<p>A variation of DixonD's excellent answer (above).</p>\n\n<pre><code>public static bool TryOpen(string path,\n                           FileMode fileMode,\n                           FileAccess fileAccess,\n                           FileShare fileShare,\n                           TimeSpan timeout,\n                           out Stream stream)\n{\n    var endTime = DateTime.Now + timeout;\n\n    while (DateTime.Now &lt; endTime)\n    {\n        if (TryOpen(path, fileMode, fileAccess, fileShare, out stream))\n            return true;\n    }\n\n    stream = null;\n    return false;\n}\n\npublic static bool TryOpen(string path,\n                           FileMode fileMode,\n                           FileAccess fileAccess,\n                           FileShare fileShare,\n                           out Stream stream)\n{\n    try\n    {\n        stream = File.Open(path, fileMode, fileAccess, fileShare);\n        return true;\n    }\n    catch (IOException e)\n    {\n        if (!FileIsLocked(e))\n            throw;\n\n        stream = null;\n        return false;\n    }\n}\n\nprivate const uint HRFileLocked = 0x80070020;\nprivate const uint HRPortionOfFileLocked = 0x80070021;\n\nprivate static bool FileIsLocked(IOException ioException)\n{\n    var errorCode = (uint)Marshal.GetHRForException(ioException);\n    return errorCode == HRFileLocked || errorCode == HRPortionOfFileLocked;\n}\n</code></pre>\n\n<p>Usage:</p>\n\n<pre><code>private void Sample(string filePath)\n{\n    Stream stream = null;\n\n    try\n    {\n        var timeOut = TimeSpan.FromSeconds(1);\n\n        if (!TryOpen(filePath,\n                     FileMode.Open,\n                     FileAccess.ReadWrite,\n                     FileShare.ReadWrite,\n                     timeOut,\n                     out stream))\n            return;\n\n        // Use stream...\n    }\n    finally\n    {\n        if (stream != null)\n            stream.Close();\n    }\n}\n</code></pre>\n"}, {'answer_id': 18989377, 'author': 'live-love', 'author_id': 436341, 'author_profile': 'https://Stackoverflow.com/users/436341', 'pm_score': 3, 'selected': False, 'text': "<p>Here's a variation of DixonD's code that adds number of seconds to wait for file to unlock, and try again:</p>\n\n<pre><code>public bool IsFileLocked(string filePath, int secondsToWait)\n{\n    bool isLocked = true;\n    int i = 0;\n\n    while (isLocked &amp;&amp;  ((i &lt; secondsToWait) || (secondsToWait == 0)))\n    {\n        try\n        {\n            using (File.Open(filePath, FileMode.Open)) { }\n            return false;\n        }\n        catch (IOException e)\n        {\n            var errorCode = Marshal.GetHRForException(e) &amp; ((1 &lt;&lt; 16) - 1);\n            isLocked = errorCode == 32 || errorCode == 33;\n            i++;\n\n            if (secondsToWait !=0)\n                new System.Threading.ManualResetEvent(false).WaitOne(1000);\n        }\n    }\n\n    return isLocked;\n}\n\n\nif (!IsFileLocked(file, 10))\n{\n    ...\n}\nelse\n{\n    throw new Exception(...);\n}\n</code></pre>\n"}, {'answer_id': 20619061, 'author': 'Bart Calixto', 'author_id': 826568, 'author_profile': 'https://Stackoverflow.com/users/826568', 'pm_score': -1, 'selected': False, 'text': '<p>What I ended up doing is:</p>\n\n<pre><code>internal void LoadExternalData() {\n    FileStream file;\n\n    if (TryOpenRead("filepath/filename", 5, out file)) {\n        using (file)\n        using (StreamReader reader = new StreamReader(file)) {\n         // do something \n        }\n    }\n}\n\n\ninternal bool TryOpenRead(string path, int timeout, out FileStream file) {\n    bool isLocked = true;\n    bool condition = true;\n\n    do {\n        try {\n            file = File.OpenRead(path);\n            return true;\n        }\n        catch (IOException e) {\n            var errorCode = Marshal.GetHRForException(e) &amp; ((1 &lt;&lt; 16) - 1);\n            isLocked = errorCode == 32 || errorCode == 33;\n            condition = (isLocked &amp;&amp; timeout &gt; 0);\n\n            if (condition) {\n                // we only wait if the file is locked. If the exception is of any other type, there\'s no point on keep trying. just return false and null;\n                timeout--;\n                new System.Threading.ManualResetEvent(false).WaitOne(1000);\n            }\n        }\n    }\n    while (condition);\n\n    file = null;\n    return false;\n}\n</code></pre>\n'}, {'answer_id': 20623302, 'author': 'Eric J.', 'author_id': 141172, 'author_profile': 'https://Stackoverflow.com/users/141172', 'pm_score': 7, 'selected': False, 'text': '<p><strong>The other answers rely on old information.  This one provides a better solution.</strong></p>\n\n<p>Long ago it was impossible to reliably get the list of processes locking a file because Windows simply did not track that information.  To support the <a href="http://msdn.microsoft.com/en-us/library/windows/desktop/aa373656%28v=vs.85%29.aspx" rel="noreferrer">Restart Manager API</a>, that information is now tracked.  The Restart Manager API is available beginning with Windows Vista and Windows Server 2008 (<a href="https://msdn.microsoft.com/en-us/library/windows/desktop/cc948910(v=vs.85).aspx" rel="noreferrer">Restart Manager: Run-time Requirements</a>).</p>\n\n<p>I put together code that takes the path of a file and returns a <code>List&lt;Process&gt;</code> of all processes that are locking that file.</p>\n\n<pre><code>static public class FileUtil\n{\n    [StructLayout(LayoutKind.Sequential)]\n    struct RM_UNIQUE_PROCESS\n    {\n        public int dwProcessId;\n        public System.Runtime.InteropServices.ComTypes.FILETIME ProcessStartTime;\n    }\n\n    const int RmRebootReasonNone = 0;\n    const int CCH_RM_MAX_APP_NAME = 255;\n    const int CCH_RM_MAX_SVC_NAME = 63;\n\n    enum RM_APP_TYPE\n    {\n        RmUnknownApp = 0,\n        RmMainWindow = 1,\n        RmOtherWindow = 2,\n        RmService = 3,\n        RmExplorer = 4,\n        RmConsole = 5,\n        RmCritical = 1000\n    }\n\n    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]\n    struct RM_PROCESS_INFO\n    {\n        public RM_UNIQUE_PROCESS Process;\n\n        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_APP_NAME + 1)]\n        public string strAppName;\n\n        [MarshalAs(UnmanagedType.ByValTStr, SizeConst = CCH_RM_MAX_SVC_NAME + 1)]\n        public string strServiceShortName;\n\n        public RM_APP_TYPE ApplicationType;\n        public uint AppStatus;\n        public uint TSSessionId;\n        [MarshalAs(UnmanagedType.Bool)]\n        public bool bRestartable;\n    }\n\n    [DllImport("rstrtmgr.dll", CharSet = CharSet.Unicode)]\n    static extern int RmRegisterResources(uint pSessionHandle,\n                                          UInt32 nFiles,\n                                          string[] rgsFilenames,\n                                          UInt32 nApplications,\n                                          [In] RM_UNIQUE_PROCESS[] rgApplications,\n                                          UInt32 nServices,\n                                          string[] rgsServiceNames);\n\n    [DllImport("rstrtmgr.dll", CharSet = CharSet.Auto)]\n    static extern int RmStartSession(out uint pSessionHandle, int dwSessionFlags, string strSessionKey);\n\n    [DllImport("rstrtmgr.dll")]\n    static extern int RmEndSession(uint pSessionHandle);\n\n    [DllImport("rstrtmgr.dll")]\n    static extern int RmGetList(uint dwSessionHandle,\n                                out uint pnProcInfoNeeded,\n                                ref uint pnProcInfo,\n                                [In, Out] RM_PROCESS_INFO[] rgAffectedApps,\n                                ref uint lpdwRebootReasons);\n\n    /// &lt;summary&gt;\n    /// Find out what process(es) have a lock on the specified file.\n    /// &lt;/summary&gt;\n    /// &lt;param name="path"&gt;Path of the file.&lt;/param&gt;\n    /// &lt;returns&gt;Processes locking the file&lt;/returns&gt;\n    /// &lt;remarks&gt;See also:\n    /// http://msdn.microsoft.com/en-us/library/windows/desktop/aa373661(v=vs.85).aspx\n    /// http://wyupdate.googlecode.com/svn-history/r401/trunk/frmFilesInUse.cs (no copyright in code at time of viewing)\n    /// \n    /// &lt;/remarks&gt;\n    static public List&lt;Process&gt; WhoIsLocking(string path)\n    {\n        uint handle;\n        string key = Guid.NewGuid().ToString();\n        List&lt;Process&gt; processes = new List&lt;Process&gt;();\n\n        int res = RmStartSession(out handle, 0, key);\n\n        if (res != 0)\n            throw new Exception("Could not begin restart session.  Unable to determine file locker.");\n\n        try\n        {\n            const int ERROR_MORE_DATA = 234;\n            uint pnProcInfoNeeded = 0,\n                 pnProcInfo = 0,\n                 lpdwRebootReasons = RmRebootReasonNone;\n\n            string[] resources = new string[] { path }; // Just checking on one resource.\n\n            res = RmRegisterResources(handle, (uint)resources.Length, resources, 0, null, 0, null);\n\n            if (res != 0) \n                throw new Exception("Could not register resource.");                                    \n\n            //Note: there\'s a race condition here -- the first call to RmGetList() returns\n            //      the total number of process. However, when we call RmGetList() again to get\n            //      the actual processes this number may have increased.\n            res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, null, ref lpdwRebootReasons);\n\n            if (res == ERROR_MORE_DATA)\n            {\n                // Create an array to store the process results\n                RM_PROCESS_INFO[] processInfo = new RM_PROCESS_INFO[pnProcInfoNeeded];\n                pnProcInfo = pnProcInfoNeeded;\n\n                // Get the list\n                res = RmGetList(handle, out pnProcInfoNeeded, ref pnProcInfo, processInfo, ref lpdwRebootReasons);\n\n                if (res == 0)\n                {\n                    processes = new List&lt;Process&gt;((int)pnProcInfo);\n\n                    // Enumerate all of the results and add them to the \n                    // list to be returned\n                    for (int i = 0; i &lt; pnProcInfo; i++)\n                    {\n                        try\n                        {\n                            processes.Add(Process.GetProcessById(processInfo[i].Process.dwProcessId));\n                        }\n                        // catch the error -- in case the process is no longer running\n                        catch (ArgumentException) { }\n                    }\n                }\n                else\n                    throw new Exception("Could not list processes locking resource.");                    \n            }\n            else if (res != 0)\n                throw new Exception("Could not list processes locking resource. Failed to get size of result.");                    \n        }\n        finally\n        {\n            RmEndSession(handle);\n        }\n\n        return processes;\n    }\n}\n</code></pre>\n\n<p><strong>UPDATE</strong></p>\n\n<p>Here is another <a href="https://blogs.msdn.microsoft.com/oldnewthing/20120217-00/?p=8283" rel="noreferrer">discussion with sample code</a> on how to use the Restart Manager API.</p>\n'}, {'answer_id': 34437734, 'author': 'Thom Schumacher', 'author_id': 4991132, 'author_profile': 'https://Stackoverflow.com/users/4991132', 'pm_score': 0, 'selected': False, 'text': '<p>Same thing but in Powershell</p>\n\n<pre><code>function Test-FileOpen\n{\n    Param\n    ([string]$FileToOpen)\n    try\n    {\n        $openFile =([system.io.file]::Open($FileToOpen,[system.io.filemode]::Open))\n        $open =$true\n        $openFile.close()\n    }\n    catch\n    {\n        $open = $false\n    }\n    $open\n}\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/1304', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/121/']