无论在.NET Core还是.NET Framework中,在文件夹上使用FileSystemWatcher都无法使用File Explorer删除任何父文件夹。 文件资源管理器将询问您管理员权限。以管理员身份启动File Explorer不能解决问题。
使它起作用的唯一方法是将FileSystemWatcher设置为根驱动器,并包括子目录,这可能会导致较大的性能问题以及FSW上的缓冲区溢出。
$temp1 = $data->object->peer_id;
$temp2 = $text[1];
$mysqli->query("INSERT INTO `const` (`chat`, `peer`) VALUES ('$temp2', '$temp1')");
$user = json_decode(file_get_contents('https://api.vk.com/method/messages.getChat?chat_id='.$temp2.'&fields=name&access_token='.$user_token.'&v='.$v));
$i = 0;
while (isset($user->response->users[$i])) {
$name = $user->response->users[$i]->first_name.' '.$user->response->users[$i]->last_name; //Та строка
$user_id = $user->response->users[$i]->id;
$mysqli->query("INSERT INTO `users` (`Id`, `Name`) VALUES ('$user_id', '$name')");
$i++;
}
$request_params['message'] = 'Настроенно';
Say($request_params);
您将无法删除文件夹“一个”或“两个”。 只要将“ EnableRaisingEvents”设置为true,问题就会立即开始,但是如果您不这样做,则不会收到任何通知。
是否有办法解决此问题,还是FileSystemWatcher的替代方法?
答案 0 :(得分:0)
@EricP 给出了根本原因:FSW 内部调用 CreateFileW 以打开受监视目录三的句柄,这告诉 Windows 防止删除父文件夹一和二。
但是 CreateFileW 调用是以读+写+删除共享模式进行的,这意味着 Windows 应该允许任何其他进程删除受监视的文件夹三。
所以没有直接解决您的问题,但有一个解决方法:
先删除三个,应该释放句柄,然后删除两个和/或一个,应该允许。
这是一个没有任何 FileSystemWatcher 代码的代码示例,只是直接 Windows P/Invokes:
using Microsoft.Win32.SafeHandles;
using System;
using System.IO;
using System.Runtime.InteropServices;
namespace MyNamespace
{
public static class MyClass
{
static void Main()
{
string path = @"C:\Users\YOURUSERNAME\Desktop\parent\child";
if (!Directory.Exists(path))
{
throw new Exception("Make sure to create the directories before testing.");
}
// This will lock the directory
SafeFileHandle _directoryHandle = CreateFile(
lpFileName: path,
dwDesiredAccess: 0x0001, //FILE_LIST_DIRECTORY
dwShareMode: FileShare.Read | FileShare.Delete | FileShare.Write,
dwCreationDisposition: FileMode.Open,
dwFlagsAndAttributes:
0x02000000 /*FILE_FLAG_BACKUP_SEMANTICS*/ |
0x40000000 /*FILE_FLAG_OVERLAPPED*/
);
Console.WriteLine("Try to manually delete the 'parent' directory using File Explorer. It should fail.");
Console.WriteLine("Now try to manually delete the 'child' directory, then the 'parent' directory, using File Explorer. It should succeed.");
Console.WriteLine("Press enter to exit.");
System.Diagnostics.Debugger.Break();
_directoryHandle.Dispose();
}
internal enum BOOL : int
{
FALSE = 0,
TRUE = 1,
}
[StructLayout(LayoutKind.Sequential)]
internal struct SECURITY_ATTRIBUTES
{
internal uint nLength;
internal IntPtr lpSecurityDescriptor;
internal BOOL bInheritHandle;
}
[DllImport("kernel32.dll", EntryPoint = "CreateFileW", SetLastError = true, CharSet = CharSet.Unicode, BestFitMapping = false, ExactSpelling = true)]
private static extern unsafe SafeFileHandle CreateFilePrivate(
string lpFileName,
int dwDesiredAccess,
FileShare dwShareMode,
SECURITY_ATTRIBUTES* lpSecurityAttributes,
FileMode dwCreationDisposition,
int dwFlagsAndAttributes,
IntPtr hTemplateFile);
internal static unsafe SafeFileHandle CreateFile(
string lpFileName,
int dwDesiredAccess,
FileShare dwShareMode,
FileMode dwCreationDisposition,
int dwFlagsAndAttributes)
{
return CreateFilePrivate(lpFileName, dwDesiredAccess, dwShareMode, null, dwCreationDisposition, dwFlagsAndAttributes, IntPtr.Zero);
}
}
}