Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何删除文件锁_C#_.net - Fatal编程技术网

C# 如何删除文件锁

C# 如何删除文件锁,c#,.net,C#,.net,我有一个将文件从工作文件夹移动到备份文件夹的服务。文件夹位于网络共享上,因此有时我们会打开一个文件,使用记事本之类的东西查看它。人们不是(嗯,不应该)在编辑,只是在看 当我们尝试移动文件时,我的权限被拒绝。我正在寻找一种在C#中强制删除文件锁的方法,以便服务可以将文件移动到备份文件夹。您必须使用p/Invoke。以下是您关心的功能: [DllImport("netapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] static

我有一个将文件从工作文件夹移动到备份文件夹的服务。文件夹位于网络共享上,因此有时我们会打开一个文件,使用记事本之类的东西查看它。人们不是(嗯,不应该)在编辑,只是在看


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

您必须使用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
    }
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
结构文件信息3
{
公共int fi3_id;
公共int fi3_许可;
公共int fi3_num_锁;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串fi3_路径名;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串fi3_用户名;
}
私有静态文件\u INFO\u 3[]GetLockedFiles(字符串服务器,字符串路径)
{
const int MAX_PREFERRED_LENGTH=-1;
int-dwReadEntries;
int dwTotalEntries;
IntPtr pBuffer=IntPtr.Zero;
FILE_INFO_3 pCurrent=新文件_INFO_3();
列表文件=新列表();
int dwStatus=NetFileEnum(服务器,路径,null,3,ref pBuffer,最大首选长度,out dwReadEntries,out dwTotalEntries,IntPtr.Zero);
如果(dwStatus==0)
{
对于(int-dwIndex=0;dwIndex

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

您必须使用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
    }
}
[StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto)]
结构文件信息3
{
公共int fi3_id;
公共int fi3_许可;
公共int fi3_num_锁;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串fi3_路径名;
[Marshallas(UnmanagedType.LPWStr)]
公共字符串fi3_用户名;
}
私有静态文件\u INFO\u 3[]GetLockedFiles(字符串服务器,字符串路径)
{
const int MAX_PREFERRED_LENGTH=-1;
int-dwReadEntries;
int dwTotalEntries;
IntPtr pBuffer=IntPtr.Zero;
FILE_INFO_3 pCurrent=新文件_INFO_3();
列表文件=新列表();
int dwStatus=NetFileEnum(服务器,路径,null,3,ref pBuffer,最大首选长度,out dwReadEntries,out dwTotalEntries,IntPtr.Zero);
如果(dwStatus==0)
{
对于(int-dwIndex=0;dwIndex

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

很酷,我给了他们一个机会。我没有否决投票,但我想这可能会导致一些文件损坏或不完整?复制文件而不关闭文件可能更安全。因此,可能更安全的方法是锁定文件,将文件复制到新位置,然后关闭锁。另外,我得到了错误访问被拒绝(NetFileEnum返回5)。我发现了与你发布的代码相似的代码,得到了5。我刚试过你的,我得到了同样的5分。谢谢你的代码,顺便说一句。@BCarlson你是网络共享所在服务器的管理员吗?你需要这样。我发现在64位上,代码略有不同。pBuffer.ToInt32变为pBuffer.ToInt64。这就是我找到答案的地方:酷,我给了他们一次机会。我没有否决投票,但我想这会导致一些文件损坏或不完整?复制文件而不关闭文件可能更安全。因此,可能更安全的方法是锁定文件,将文件复制到新位置,然后关闭锁。另外,我得到了错误访问被拒绝(NetFileEnum返回5)。我发现了与你发布的代码相似的代码,得到了5。我刚试过你的,我得到了同样的5分。谢谢你的代码,顺便说一句。@BCarlson你是网络共享所在服务器的管理员吗?你需要这样。我发现在64位上,代码略有不同。pBuffer.ToInt32变为pBuffer.ToInt64。这就是我找到答案的地方:这是在windows上吗?如果您有关键文件,请将其设为其他用户的只读文件,否则任何进程都会锁定它。听起来您想复制它们而不是移动它们?复制后,“移动”将从源文件夹中删除文件。这是否在windows上?如果您有关键文件,请将其设为其他用户的只读文件,否则任何进程都会锁定它。听起来您想复制它们而不是移动它们?复制后,move将从源文件夹中删除文件。