Как использовать File.Move вместе с FileSystemWatcher?

Рейтинг: 1Ответов: 0Опубликовано: 27.04.2023

Программа отслеживает изменения в выбранной директории (создание, удаление, переименование, перемещение и изменение файлов). Выводит сообщения обо всем происходящем в richTextBox. Так вот, траблы:

  1. При создании файлов (особенно с расширениями.xlsx и .bmp) все падает и выбрасывает ошибку "Процесс не может получить доступ к файлу, так как этот файл занят другим процессом.". Это потому что Watcher.Created и File.Move поток не поделили?
  2. В функции Watcher_Created не могу использовать watcher.EnableRaisingEvents = false из функции syswatcher. Как мне его туда передать?

Листинг:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;
using System.Reflection.Emit;
using System.Threading;


namespace ScanDirectory
{
    public partial class ScanDirectory : Form
    {
        string FolderPath { get; set; }

        private void Watcher_Created(object s, FileSystemEventArgs e)
        {
            richTextBox1.Text += $"{DateTime.Now} Файл {e.Name} создан\n";
            string fileName = e.Name;

            if (fileName == "ошибка.txt")
            {
                string errorContent = File.ReadAllText(e.FullPath);
                richTextBox1.Text += $"{DateTime.Now} Ошибка: \n {errorContent}\n";
                MessageBox.Show("Ошибка!");
            }
            else if (fileName == "конец.txt")
            {
                if(MessageBox.Show("Работа программы успешно завершена!") == DialogResult.OK)
                {
                    Application.Exit();
                }
            }
            else
            {
                string extension = Path.GetExtension(fileName);
                if (extension != "")
                {
                    string destinationFolder = Path.Combine(FolderPath, extension.Substring(1));
                    CreateDir(destinationFolder);
                    string sourceFile = Path.Combine(FolderPath, fileName);
                    string destinationFile = Path.Combine(destinationFolder, fileName);
                    MoveFile(sourceFile, destinationFile, e);
                }
            }
        }

        private static void CreateDir(string destinationFolder)
        {
            if (!Directory.Exists(destinationFolder))
                Directory.CreateDirectory(destinationFolder);
        }

        private void MoveFile(string sourceFile, string destinationFile, FileSystemEventArgs e)
        {
            if (!File.Exists(destinationFile))
            {
                File.Move(sourceFile, destinationFile);
            }
            else
                richTextBox1.Text += $"{DateTime.Now} Файл {e.Name} не был перемещен. Требуется переименование.\n";
        }

        void Watcher_Deleted(object s, FileSystemEventArgs e)
        {
            richTextBox1.Text += $"{DateTime.Now} Файл {e.Name} удален\n";
        }

        void Watcher_Renamed(object s, RenamedEventArgs e)
        {
            richTextBox1.Text += $"{DateTime.Now} Файл {e.OldName} переименован в {e.Name}\n";
        }

        void Watcher_Changed(object s, FileSystemEventArgs e)
        {

            richTextBox1.Text += $"{DateTime.Now} Файл {e.Name} изменен\n";
        }

        private void BrowseFolder_Click(object s, EventArgs e)
        {
            FolderBrowserDialog fbd = new FolderBrowserDialog();
            fbd.Description = "Выберите папку для мониторинга";
            if (fbd.ShowDialog() == DialogResult.OK)
                MessageBox.Show("Выбрана папка: " + fbd.SelectedPath);
            FolderPath = fbd.SelectedPath;
            syswatcher(FolderPath);
        }

        public void syswatcher(string FolderPath)
        {
            FileSystemWatcher watcher = new FileSystemWatcher(FolderPath);
            watcher.EnableRaisingEvents = true;
            watcher.SynchronizingObject = this;

            watcher.Created += new FileSystemEventHandler(Watcher_Created);
            watcher.Deleted += new FileSystemEventHandler(Watcher_Deleted);
            watcher.Renamed += new RenamedEventHandler(Watcher_Renamed);
            watcher.Changed += new FileSystemEventHandler(Watcher_Changed);
        }

        private void Form1_Load(object s, EventArgs e)
        {

        }
        public ScanDirectory()
        {
            InitializeComponent();
        }

    }
}

Пробовал:

  1. в функции MoveFile и CreateDir добавить this.Close(). Оно закрывает саму программу ;)
  2. в функции MoveFile и CreateDir добавить Thread.Sleep(100). Тогда он не может найти Excel файл для перемещения и выдает ошибку.

Ответы

Ответов пока нет.