如何删除文件锁

时间:2016-08-05 15:52:13

标签: c# .net

我有一项服务将文件从工作文件夹移动到备份文件夹。这些文件夹位于网络共享上,因此我们有时会使用记事本这样的文件打开文件来查看它。人们不是(好吧,不应该)编辑,只是看。

当我们尝试移动文件时,我获得了许可被拒绝。我在C#中寻找一种强制删除文件锁的方法,因此服务可以将文件移动到备份文件夹。

1 个答案:

答案 0 :(得分:2)

你必须使用P / Invoke。这些是你关心的功能:

[DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern int NetFileEnum(string servername, string basepath, string username, int level, ref IntPtr bufptr, int prefmaxlen, out int entriesread, out int totalentries, IntPtr resume_handle);

[DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
static extern int NetFileClose(string servername, int id);

[DllImport("Netapi32.dll", SetLastError = true)]
static extern int NetApiBufferFree(IntPtr buffer);

这里有一些类似于我成功使用的代码:

[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
struct FILE_INFO_3
{
    public int fi3_id;
    public int fi3_permission;
    public int fi3_num_locks;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string fi3_pathname;
    [MarshalAs(UnmanagedType.LPWStr)]
    public string fi3_username;
}

private static FILE_INFO_3[] GetLockedFiles(string server, string path)
{
    const int MAX_PREFERRED_LENGTH = -1;

    int dwReadEntries;
    int dwTotalEntries;
    IntPtr pBuffer = IntPtr.Zero;
    FILE_INFO_3 pCurrent = new FILE_INFO_3();
    List<FILE_INFO_3> files = new List<FILE_INFO_3>();

    int dwStatus = NetFileEnum(server, path, null, 3, ref pBuffer, MAX_PREFERRED_LENGTH, out dwReadEntries, out dwTotalEntries, IntPtr.Zero);
    if (dwStatus == 0)
    {
        for (int dwIndex = 0; dwIndex < dwReadEntries; dwIndex++)
        {
            IntPtr iPtr = new IntPtr(pBuffer.ToInt32() + (dwIndex * Marshal.SizeOf(pCurrent)));
            pCurrent = (FILE_INFO_3)Marshal.PtrToStructure(iPtr, typeof(FILE_INFO_3));
            files.Add(pCurrent);
        }
    }

    NetApiBufferFree(pBuffer);

    return files.ToArray();
}

static void Main(string[] args)
{
    FILE_INFO_3[] lockedFiles = GetLockedFiles("someservername", @"C:\somepath");

    foreach (FILE_INFO_3 lockedFile in lockedFiles)
    {
        int dwStatus = NetFileClose(_serverName, lockedFile.fi3_id);
        // Check dwStatus for success here
    }
}

编辑:正如下面评论中的OP所述,当编译为64位时,您需要使用ToInt64而不是ToInt32。可以找到更多信息here