2016-08-05 76 views
0

我有一个服务来将文件从工作文件夹移动到备份文件夹。这些文件夹位于网络共享上,所以有时我们会使用诸如记事本之类的东西来打开文件来查看它。人们不是(好,不应该)正在编辑,只是看。如何删除文件锁

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

+1

这是在Windows上吗?如果你有关键文件,那么让它们对其他用户是只读的,否则任何进程都可以锁定它。 – muratgu

+0

听起来像你想**复制**他们而不是移动?移动将复制后从源文件夹中删除文件。 – Slai

回答

1

您必须使用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找到。

+0

很酷,我给他们一个镜头。 – BCarlson

+0

有人解释downvote? – itsme86

+0

我没有投票,但我想这可以留下一些文件损坏或不完整?可能更安全地复制文件而不关闭它。 – Slai