/// <summary>
        /// Create a new event arguments from the specified information.
        /// </summary>
        /// <param name="inf"></param>
        /// <param name="wnd"></param>
        /// <returns></returns>
        /// <remarks></remarks>
        internal static FSMonitorEventArgs FromPtr(FILE_NOTIFY_INFORMATION inf, FSMonitor wnd)
        {
            var fsm = new FSMonitorEventArgs();

            fsm._Info    = new FileNotifyInfo(inf);
            fsm._sender  = wnd;
            fsm._Storage = wnd.Storage;
            return(fsm);
        }
Example #2
0
        private void _FSMon_WatchNotifyChange(object sender, FSMonitorEventArgs e)
        {
            var inf = e.Info;

            do
            {
                // right now we've configured it for adding.
                // you can comment out the If block, or change the
                // condition to see other results.
                if (inf.Action == FileActions.Added)
                {
                    NotifyCol.Add(inf);
                }

                inf = inf.NextEntry;
            }while (!(inf is null));
            this.Status.Text = this.ViewingArea.Items.Count + " total items.";
        }
        /// <summary>
        /// Internally creates and starts the monitor thread.
        /// </summary>
        /// <returns>
        /// True if the thread was successfully created.
        /// To ensure the monitor was successfully activated, handle the MonitorOpened event.
        /// </returns>
        /// <remarks></remarks>
        protected bool internalWatch()
        {
            int blen    = 0;
            int bufflen = (int)_Buff.Size;
            var tbuff   = _Buff.Handle;

            if (_thread is object)
            {
                return(false);
            }
            if (!internalOpenFile())
            {
                return(false);
            }
            FILE_NOTIFY_INFORMATION fn;

            fn.ptr  = _Buff;
            _thread = new System.Threading.Thread(() =>
            {
                var notice = IntPtr.Zero;
                User32.PostMessage(Handle, FileSystemMonitor.WM_SIGNAL_OPEN, IntPtr.Zero, IntPtr.Zero);
                do
                {
                    try
                    {
                        // let's clean up the memory before the next execute.
                        if (blen > 0)
                        {
                            _Buff.ZeroMemory(0L, blen);
                            blen = 0;
                        }

                        if (!FileSystemMonitor.ReadDirectoryChangesW(_hFile, tbuff, bufflen, true, _Filter, ref blen, IntPtr.Zero, IntPtr.Zero))
                        {
                            notice = (IntPtr)User32.GetLastError();
                            break;
                        }
                    }
                    catch (System.Threading.ThreadAbortException)
                    {
                        break;
                    }
                    catch (Exception)
                    {
                        notice = (IntPtr)1;
                        break;
                    }

                    // block until the lock is acquired.  Hopefully the
                    // UI thread will not take that long to clean the list.
                    System.Threading.Monitor.Enter(_WaitList);
                    _WaitList.Add(FSMonitorEventArgs.FromPtr(fn, this));
                    // and we're done ...
                    System.Threading.Monitor.Exit(_WaitList);

                    // post to the UI thread that there are items to dequeue and continue!
                    User32.PostMessage(Handle, FileSystemMonitor.WM_SIGNAL, IntPtr.Zero, IntPtr.Zero);
                }while (true);
                _thread = null;
                User32.PostMessage(Handle, FileSystemMonitor.WM_SIGNAL_CLOSE, IntPtr.Zero, IntPtr.Zero);
            });

            _thread.SetApartmentState(System.Threading.ApartmentState.STA);
            _thread.IsBackground = true;

            _thread.Start();

            return(true);
        }