Как использовать File.Move вместе с FileSystemWatcher?
Программа отслеживает изменения в выбранной директории (создание, удаление, переименование, перемещение и изменение файлов). Выводит сообщения обо всем происходящем в richTextBox. Так вот, траблы:
- При создании файлов (особенно с расширениями.xlsx и .bmp) все падает и выбрасывает ошибку "Процесс не может получить доступ к файлу, так как этот файл занят другим процессом.". Это потому что Watcher.Created и File.Move поток не поделили?
- В функции 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();
}
}
}
Пробовал:
- в функции MoveFile и CreateDir добавить this.Close(). Оно закрывает саму программу ;)
- в функции MoveFile и CreateDir добавить Thread.Sleep(100). Тогда он не может найти Excel файл для перемещения и выдает ошибку.
Источник: Stack Overflow на русском