5

I have been trying to lock a file so that other cloned services cannot access the file. I then read the file, and then move the file when finished. The Move is allowed by using FileShare.Delete.

However in later testing, we found that this approach does not work if we are looking at a network share. I appreciate my approach may not have been the best, but my specific question is:

Why does the below demo work against the local file, but not against the network file?

The more specific you can be the better, as I've found very little information in my searches that indicates network shares behave differently to local disks.

string sourceFile = @"C:\TestFile.txt";
string localPath = @"C:\MyLocalFolder\TestFile.txt";
string networkPath = @"\\MyMachine\MyNetworkFolder\TestFile.txt";

File.WriteAllText(sourceFile, "Test data");

if (!File.Exists(localPath))
    File.Copy(sourceFile, localPath);

foreach (string path in new string[] { localPath, networkPath })
{
    using (FileStream fsLock = File.Open(path, FileMode.Open, FileAccess.ReadWrite, (FileShare.Read | FileShare.Delete)))
    {
        string target = path + ".out";
        File.Move(path, target); //This is the point of failure, when working with networkPath

        if (File.Exists(target))
            File.Delete(target);
    }

    if (!File.Exists(path))
        File.Copy(sourceFile, path);
}

EDIT: It's worth mentioning that if you wish to move the file from one network share, to another network share while the lock is in place, this works. The problem only seems to occur when moving a file within the same file share while it is locked.

MattH
  • 4,166
  • 2
  • 29
  • 33
  • Check if you have permissions to write in shared folder. – Nayan Apr 23 '10 at 10:20
  • Permissions have been checked, and are fine. Active user has Full Control on directory and Share – MattH Apr 23 '10 at 10:41
  • What kind of operating system provides the share? – Hans Passant Apr 23 '10 at 11:51
  • This was originally seen on a Windows 2003 Server. I recreated it using the above code on a Windows XP Professional SP3, using a network share pointing to the local drive. – MattH Apr 23 '10 at 13:18
  • 1
    The sqlite team [reports](http://www.sqlite.org/atomiccommit.html#brokenlocks) potential problems with network file locks and recommends not to use them. (Note that their observations are of a general nature, not sqlite-specific.) – Marcelo Cantos Apr 25 '10 at 12:41
  • @MarceloCantos Good thing SMB3 is head and tails better than SMB2. – Brain2000 Jan 10 '16 at 01:32

1 Answers1

3

I believe System.IO.File.Open() maps to the Win32 API function CreateFile(). In Microsoft's documentation for this function [ http://msdn.microsoft.com/en-us/library/aa363858(v=vs.85).aspx ], it mentions the following:

Windows Server 2003 and Windows XP/2000: A sharing violation occurs if an attempt is made to open a file or directory for deletion on a remote computer when the value of the dwDesiredAccess parameter is the DELETE access flag (0x00010000) OR'ed with any other access flag, and the remote file or directory has not been opened with FILE_SHARE_DELETE. To avoid the sharing violation in this scenario, open the remote file or directory with the DELETE access right only, or call DeleteFile without first opening the file or directory for deletion.

According to this, you would have to pass DELETE as the FileAccess parameter to IO.File.Open(). Unfortunately, the DELETE enumeration was not included as an option.

This problem only pertains to Windows 2003 and earlier. I have tested your code on Windows 2008 R2 SP1, and it works fine. So it is possible that it would also work on Windows 2008 as well.

Brain2000
  • 4,655
  • 2
  • 27
  • 35