Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/22.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# FileSystemWatcher锁定父文件夹,是否有修复方法或替代方法?_C#_.net - Fatal编程技术网

C# FileSystemWatcher锁定父文件夹,是否有修复方法或替代方法?

C# FileSystemWatcher锁定父文件夹,是否有修复方法或替代方法?,c#,.net,C#,.net,无论是在.NET Core还是.NET Framework中,在文件夹上使用FileSystemWatcher都无法使用文件资源管理器删除任何父文件夹。 文件资源管理器将要求您获得管理员权限。以管理员身份启动文件资源管理器无法解决此问题 我能让它工作的唯一方法是将FileSystemWatcher设置为根驱动器,并包括子目录,这可能会导致严重的性能问题,以及FSW上的缓冲区溢出 FileSystemWatcher fsw = new FileSystemWatcher(@"C:\One\Two\

无论是在.NET Core还是.NET Framework中,在文件夹上使用FileSystemWatcher都无法使用文件资源管理器删除任何父文件夹。 文件资源管理器将要求您获得管理员权限。以管理员身份启动文件资源管理器无法解决此问题

我能让它工作的唯一方法是将FileSystemWatcher设置为根驱动器,并包括子目录,这可能会导致严重的性能问题,以及FSW上的缓冲区溢出

FileSystemWatcher fsw = new FileSystemWatcher(@"C:\One\Two\Three");
fsw.EnableRaisingEvents = true;
您将无法删除文件夹“一个”或“两个”。 一旦将“EnableRaisingEvents”设置为true,问题就会出现,但如果不设置,则不会收到任何通知


有什么方法可以克服这个问题,或者是FileSystemWatcher的替代方案吗?

@EricP给出了根本原因:FSW在内部调用CreateFileW以打开受监视目录3的句柄,该句柄告诉Windows防止删除父文件夹1和父文件夹2

但是CreateFileW调用是以读+写+删除共享模式进行的,这意味着Windows应该允许任何其他进程删除受监视的文件夹

因此,您的问题没有直接的解决方法,但有一个解决方法:

首先删除三个,这将释放句柄,然后删除两个和/或一个,这应该是允许的

下面是一个代码示例,在没有任何FileSystemWatcher代码的情况下重新编写此代码,只需直接调用Windows p/Invokes即可:

使用Microsoft.Win32.SafeHandles;
使用制度;
使用System.IO;
使用System.Runtime.InteropServices;
名称空间MyNamespace
{
公共静态类MyClass
{
静态void Main()
{
字符串路径=@“C:\Users\YOURUSERNAME\Desktop\parent\child”;
如果(!Directory.Exists(path))
{
抛出新异常(“确保在测试之前创建目录”);
}
//这将锁定目录
SafeFileHandle\u directoryHandle=CreateFile(
lpFileName:path,
dwDesiredAccess:0x0001,//文件\列表\目录
dwShareMode:FileShare.Read | FileShare.Delete | FileShare.Write,
dwCreationDisposition:FileMode.Open,
dwFlagsAndAttributes:
0x020000000/*文件\u标志\u备份\u语义*/|
0x40000000/*文件\u标志\u重叠*/
);
WriteLine(“尝试使用文件资源管理器手动删除“父”目录。它应该失败。”);
WriteLine(“现在尝试使用文件资源管理器手动删除'child'目录,然后删除'parent'目录。应该成功。”);
控制台。WriteLine(“按enter键退出”);
System.Diagnostics.Debugger.Break();
_directoryHandle.Dispose();
}
内部枚举布尔值:int
{
FALSE=0,
真=1,
}
[StructLayout(LayoutKind.Sequential)]
内部结构安全属性
{
内部单元长度;
内部IntPtr lpSecurityDescriptor;
内部BOOL bInheritHandle;
}
[DllImport(“kernel32.dll”,EntryPoint=“CreateFileW”,SetLastError=true,CharSet=CharSet.Unicode,BestFitMapping=false,ExactSpelling=true)]
私有静态外部不安全的SafeFileHandle CreateFilePrivate(
字符串lpFileName,
int DWD期望访问,
文件共享模式,
安全属性*lpSecurityAttributes,
文件模式dwCreationDisposition,
int dwFlagsAndAttributes,
IntPtr-hTemplateFile);
内部静态不安全的SafeFileHandle CreateFile(
字符串lpFileName,
int DWD期望访问,
文件共享模式,
文件模式dwCreationDisposition,
int dwFlagsAndAttributes)
{
返回CreateFilePrivate(lpFileName、dwDesiredAccess、dwShareMode、null、dwCreationDisposition、dwFlagsAndAttributes、IntPtr.Zero);
}
}
}

不应该,请参阅。您可以创建一个文件吗?但是没有指定要添加哪些类型的文件更改filewatcher。您应该使用“NotifyFilter”。种类文件属性太多了,您计划的目标是哪一个?@CodeCaster我以前读过您的链接,这不是同一个问题。在您的链接上,它是由第二个FileSystemWatcher引起的。我的是关于被监视文件夹的父母。我写的两行代码足以重现问题,这是一个实际的最小可重现性示例。@ANaik当然,在我的代码中,我使用NotifyFilters、events等对其进行了充分配置。我保持了简短以突出显示问题problem@EricP. 在内部,
FSW
有一个私有方法
StartRaisingEvents
有以下行:
directoryHandle=Microsoft.Win32.NativeMethods.CreateFile(directory,1,7,null,31107296256,new-SafeFileHandle(IntPtr.Zero,ownsHandle:false))
在Windows中,文件句柄获取父结构上的锁,因此句柄在句柄的生存期内保持有效。问题不是由FSW本身引起的;这是由WINAPI的工作方式引起的。