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

时间:2019-07-10 18:40:11

标签: c# .net

无论在.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的替代方法?

1 个答案:

答案 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);
        }
    }
}