1) Второй параметр конструктора является необязательным, то есть мы можем следить за всеми файлами по указанному пути (как в примере ниже) , или же за определёнными файлами по маске, например "*.txt" следит за всеми текстовыми файлами. 2) Поля EnableRaisingEvents и SynchronizingObject можем задать в инициализаторе и сэкономить 2 строчки. 3) При добавлении обработчика событий можно просто указать название метода, без необходимости вызывать конструктор делегата(как в примере ниже).(да и вообще как только написали watcher.Created += жмем TAB и вижла сама всё сделает) 4) У EventArgs`ов есть интересные свойства - Name, OldName и тд(используются в примере ниже) void Form1_Load(object s, EventArgs e) { FileSystemWatcher watcher = new FileSystemWatcher(@"C:\Users\TTR\Desktop\") { EnableRaisingEvents=true, SynchronizingObject=this }; watcher.Created += Watcher_Created; watcher.Deleted += Watcher_Deleted; watcher.Renamed += Watcher_Renamed; } void Watcher_Created(object s, FileSystemEventArgs e) => label1.Text += $"Файл {e.Name} создан "; void Watcher_Deleted(object s, FileSystemEventArgs e) => label1.Text += $"Файл {e.Name} удалён "; void Watcher_Renamed(object s, RenamedEventArgs e) => label1.Text += $"Файл {e.OldName} переименован в {e.Name} "; Результат работы программы: Файл Новый текстовый документ.txt создан Файл Новый текстовый документ.txt переименован в 3.txt Файл 3.txt удалён Файл ACValhalla.exe - копия.lnk создан Файл ACValhalla.exe - копия.lnk удалён
@@RoyZASTEROiD MSDN: "Если SynchronizingObject имеет значение null , методы, обрабатывающие событие, вызываются в потоке из пула системных потоков. Если событие обрабатывается компонентом Windows Forms, например Button , доступ к компоненту через пул системных потоков может не работать или может привести к исключению. Это следует избегать, если задать SynchronizingObject компоненту Windows Forms, в результате чего методы, обрабатывающие событие, вызываются в том же потоке, в котором был создан компонент."
Здравствуйте. Возник вопрос: А как сделать чтобы файл 1.txt (как было в примере) было невозможно удалить, переименовать, переместить и редактировать, пока работает программа? Или это делается не с помощью FileSystemWatcher?
Здравствуйте, а вы случайно когда-то не сталкивались с такой проблемой: у меня в студии в шаблонах проекта почему-то нет WinForms .NET Core, только .NET Framework есть. Всё в установщике нужное вроде стоит, могу создавать консольку и библиотеки на .NET Core
@@XpucT Ну там не совсем логично. Я провел эксперимент. Слежу за пустой папкой. И по событию Created копирую этот файл в другую папку. Так вот, по событию копируется пустой файл, размером 0 KB. Так же, в описании класса сказано, что по мере записи файла, еще может вызываться несколько событий Changed. А как отследить окончание записи файла нигде не сказано (:
Такой вопрос: При создании файла он это не видит. Created видит только когда файл копируется на рабочий стол, когда возвращают с корзины видимо как в видео, НО, не создание. Чем может решится? Вот код: void Watcher_Deleted(object sender, FileSystemEventArgs e) => label4.Text = $"Куда удалил файлик? Я всё видел. Ты это сделал в {DateTime.Now}"; void Watcher_Created(object s, FileSystemEventArgs e) => label4.Text = $"Файл сделан {DateTime.Now}"; private void Form1_Load(object sender, EventArgs e) { FileSystemWatcher watcher = new FileSystemWatcher(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "123.txt"); watcher.EnableRaisingEvents = true; //позволяет пихать методы watcher.SynchronizingObject = this; //синхронизация с файловой системой watcher.Deleted += new FileSystemEventHandler(Watcher_Deleted); watcher.Created += new FileSystemEventHandler(Watcher_Created); }
@@XpucT пользователя я то могу узнать кто в данном моменте работает за компютером: textBox1.Text = string.Format("{0}\\{1}", Environment.UserDomainName, Environment.UserName); Но как отследить открывал ли он определенный файл! Пробовал по Диспетчер задач отследить, но работает только если я компьютером пользуюсь: var processes = from p in Process.GetProcessesByName("excel") select p; foreach (var process in processes) { if (process.MainWindowTitle == excelFileName) { listBox1.Items.Add(process.MainWindowTitle); } if (listBox1.Items.Contains("2022.xlsx - Excel")) { label9.Text = DateTime.Now + " " + textBox1.Text + " " + "Открыл Файл"; } } Если на этом же компьютере залогинился другой то все это неработает. Программа у меня запускается при каждой смене пользователя.
@@felikssstepanovs2861 в любой смене пользователя, в любой среде и при любой учётке при первом обращении или изменении файла сразу же в лог кидаешь Username и всё. Либо Я чего-то не пойму до сих пор. Откуда ни торкай файл Username будет именно того, кто торкает.
@@XpucT Вот этот код работает, но я думаю он слишком кривой. Может можно как то иначе? // Когда программа запускается то button1 сама нажимается каждые 5 секунд private void button1_Click(object sender, EventArgs e) { try { using (Stream stream = new FileStream("C:\\1.txt", FileMode.Open)) label1.Text = "Файл не открыт"; } catch { label1.Text = "Файл открыт"; } if (label1.Text == "Файл открыт") { //тут обработка информации - записывается в лог файл кто когда открыл файл 1.txt } }
Странно если файл изменить 1 раз watcher_changed { label4.Text = (i += 1).ToString() } То число будет равным 2! Я просмотрел в debug И о чуда там цикл в 2 прохода. Почему?
Добрый день. Очень классно рассказали. Но я нашел одну проблему, функция создания файла срабатывает сразу как только файл создан. НО, если файл очень большой и он ещё качается, например размер файла 1 гб, который качается еще, как отследить когда он полностью скачается. Ведь функция создания сразу срабатывает. Но файл еще не готов.
Добрый 🖐 Для специфического или конкретного отслеживания, лучше, конечно, дополнять своими сценариями. То есть if (new FileInfo...) Замерять размер и т.д.
1) Второй параметр конструктора является необязательным, то есть мы можем следить за всеми файлами по указанному пути (как в примере ниже) , или же за определёнными файлами по маске, например "*.txt" следит за всеми текстовыми файлами.
2) Поля EnableRaisingEvents и SynchronizingObject можем задать в инициализаторе и сэкономить 2 строчки.
3) При добавлении обработчика событий можно просто указать название метода, без необходимости вызывать конструктор делегата(как в примере ниже).(да и вообще как только написали watcher.Created += жмем TAB и вижла сама всё сделает)
4) У EventArgs`ов есть интересные свойства - Name, OldName и тд(используются в примере ниже)
void Form1_Load(object s, EventArgs e)
{
FileSystemWatcher watcher = new FileSystemWatcher(@"C:\Users\TTR\Desktop\") { EnableRaisingEvents=true, SynchronizingObject=this };
watcher.Created += Watcher_Created;
watcher.Deleted += Watcher_Deleted;
watcher.Renamed += Watcher_Renamed;
}
void Watcher_Created(object s, FileSystemEventArgs e) => label1.Text += $"Файл {e.Name} создан
";
void Watcher_Deleted(object s, FileSystemEventArgs e) => label1.Text += $"Файл {e.Name} удалён
";
void Watcher_Renamed(object s, RenamedEventArgs e) => label1.Text += $"Файл {e.OldName} переименован в {e.Name}
";
Результат работы программы:
Файл Новый текстовый документ.txt создан
Файл Новый текстовый документ.txt переименован в 3.txt
Файл 3.txt удалён
Файл ACValhalla.exe - копия.lnk создан
Файл ACValhalla.exe - копия.lnk удалён
Закреп 👍
В консоль апп как использовать -SynchronizingObject=this- ? не получается использовать так.
@@RoyZASTEROiD оно там не нужно, просто не пиши
@@Max1GameChannel спс, а для чего надо SynchronizingObject можеш обяснить из видео не полностью понялф
@@RoyZASTEROiD
MSDN: "Если SynchronizingObject имеет значение null , методы, обрабатывающие событие, вызываются в потоке из пула системных потоков.
Если событие обрабатывается компонентом Windows Forms, например Button , доступ к компоненту через пул системных потоков может не работать или может привести к исключению. Это следует избегать, если задать SynchronizingObject компоненту Windows Forms, в результате чего методы, обрабатывающие событие, вызываются в том же потоке, в котором был создан компонент."
Спасибо за прекрасные уроки!
Пишу на шарпах уже почти 2 года, а об этой штуке узнал только сейчас из твоего видео. Спасибо, Хачатур! Действительно лучшие уроки по C#.
Спасибо! Очень полезно!
Спасибо! Четкая, понятная, логичная подача информации.
Здравствуйте.
Возник вопрос: А как сделать чтобы файл 1.txt (как было в примере) было невозможно удалить, переименовать, переместить и редактировать, пока работает программа?
Или это делается не с помощью FileSystemWatcher?
Ctrl + Shift + Space в помощь вместо запятой. Shift + Стрелки перегрузки методов. Спасибо за видео.
Спасибо
Хачатур, человечище! Жду продолжения !:)
Доброй ночи, пишу вам из командного центра. В прошлый раз вы отшутились на мой комментарий про редакцию Windows. Всё таки, LTSC или Pro у вас стоит?
Pro. 1055 оригинал.
@@arteria-circumflexa6527 Благодарю
Доброй 🌙
Про Windows Хачатур отвечал в Уроке 1.1.
Хачатур балует выпусками.
Здравствуйте, а вы случайно когда-то не сталкивались с такой проблемой: у меня в студии в шаблонах проекта почему-то нет WinForms .NET Core, только .NET Framework есть. Всё в установщике нужное вроде стоит, могу создавать консольку и библиотеки на .NET Core
Приходится создавать .NET Framework WinForms и с помощью .NET Upgrade переводить на .NET Core
Добрый день 🖐
Всё потому, что .NET Core нужно отдельно указывать. Если студия стояла ДО Core, то так и будет теперь, если не ошибаюсь.
@@XpucT да, стояла до .net core, но сейчас с ним, спасибо за ответ
Спасибо! А вот есть вопрос. Если файл большой, и копируется долго. Событие генерируется в какой момент?
Логично, что по заключению.
То есть если не скопирован, а только копируется, это ещё не событие.
@@XpucT Ну там не совсем логично. Я провел эксперимент. Слежу за пустой папкой. И по событию Created копирую этот файл в другую папку. Так вот, по событию копируется пустой файл, размером 0 KB. Так же, в описании класса сказано, что по мере записи файла, еще может вызываться несколько событий Changed. А как отследить окончание записи файла нигде не сказано (:
@@kostya1306 я сделал так:
public void CreateMy(string fileName)
{
Program.log.Clear();
new Thread(() =>
{
{
tryagain:
try
{
File.Copy(Path.Combine(sourceDir, fileName), Path.Combine(destinationDir, fileName), true);
}
catch (Exception ex)
{
listBox1.Items.Add(ex.Message);
goto tryagain;
}
};
Program.log.Add(DateTime.Now.ToString());
Program.log.Add("Синхронизация файла" + fileName);
}).Start();
Такой вопрос:
При создании файла он это не видит. Created видит только когда файл копируется на рабочий стол, когда возвращают с корзины видимо как в видео, НО, не создание. Чем может решится?
Вот код:
void Watcher_Deleted(object sender, FileSystemEventArgs e) => label4.Text = $"Куда удалил файлик? Я всё видел.
Ты это сделал в {DateTime.Now}";
void Watcher_Created(object s, FileSystemEventArgs e) => label4.Text = $"Файл сделан {DateTime.Now}";
private void Form1_Load(object sender, EventArgs e)
{
FileSystemWatcher watcher = new FileSystemWatcher(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "123.txt");
watcher.EnableRaisingEvents = true; //позволяет пихать методы
watcher.SynchronizingObject = this; //синхронизация с файловой системой
watcher.Deleted += new FileSystemEventHandler(Watcher_Deleted);
watcher.Created += new FileSystemEventHandler(Watcher_Created);
}
По зову сердца
Сразу лайк не глядя!
Привет Хачатур!
Мне нужно отследить, какой пользователь компьютера открыл соответствующий файл. Возможно ли с FileSystemWatcher?
Привет 🖐
По сути это просто Environment.Username.
@@XpucT пользователя я то могу узнать кто в данном моменте работает за компютером:
textBox1.Text = string.Format("{0}\\{1}", Environment.UserDomainName, Environment.UserName);
Но как отследить открывал ли он определенный файл!
Пробовал по Диспетчер задач отследить, но работает только если я компьютером пользуюсь:
var processes = from p in Process.GetProcessesByName("excel")
select p;
foreach (var process in processes)
{
if (process.MainWindowTitle == excelFileName)
{
listBox1.Items.Add(process.MainWindowTitle);
}
if (listBox1.Items.Contains("2022.xlsx - Excel"))
{
label9.Text = DateTime.Now + "
" + textBox1.Text + " " + "Открыл Файл";
}
}
Если на этом же компьютере залогинился другой то все это неработает.
Программа у меня запускается при каждой смене пользователя.
@@felikssstepanovs2861 в любой смене пользователя, в любой среде и при любой учётке при первом обращении или изменении файла сразу же в лог кидаешь Username и всё. Либо Я чего-то не пойму до сих пор. Откуда ни торкай файл Username будет именно того, кто торкает.
@@XpucT
Вот этот код работает, но я думаю он слишком кривой. Может можно как то иначе?
// Когда программа запускается то button1 сама нажимается каждые 5 секунд
private void button1_Click(object sender, EventArgs e)
{
try
{
using (Stream stream = new FileStream("C:\\1.txt", FileMode.Open))
label1.Text = "Файл не открыт";
}
catch
{
label1.Text = "Файл открыт";
}
if (label1.Text == "Файл открыт")
{
//тут обработка информации - записывается в лог файл кто когда открыл файл 1.txt
}
}
@@felikssstepanovs2861 Если код работает, то он уже не кривой.
А как следить за именно изменениями в папке? Типо: в папке был создан файл и т.д?
.Changed
@@XpucT, спасибо большое.
Странно если файл изменить 1 раз watcher_changed { label4.Text = (i += 1).ToString() } То число будет равным 2! Я просмотрел в debug И о чуда там цикл в 2 прохода. Почему?
Не обращал внимания. А i точно равен 0 изначально?
@@XpucT да i=0; само событие обрабатывается дважды оно циклично! почему?
@@XpucT или баг или перепроверка (а точно файл изменен? а может показалась? а ну-ка проверю еще O_o )
@@СерОрл-ш5м сложно сказать, возможно файл меняется + изменяется имя, но уже после доступа (изменения).
А как вывести кто удалил или переименовал файл? FileSystemWatcher умеет это вывести?
Хачатур, а как ты скопировал целую строку, когда курсор был в конце неё?
Ctrl + D
Спасибо за урок! Но у Меня есть вопрос:
Круто большое спасибо))
а нет случайно такого же наблюдателя только для диспетчера задач?(
Такого нет.
@@XpucT жаль, придется самописное делать, а по вин апи есть видео?
@@ЕгорКостин-э3ж ruclips.net/video/KYq2WF3otxc/видео.html
Добрый день. Очень классно рассказали. Но я нашел одну проблему, функция создания файла срабатывает сразу как только файл создан. НО, если файл очень большой и он ещё качается, например размер файла 1 гб, который качается еще, как отследить когда он полностью скачается. Ведь функция создания сразу срабатывает. Но файл еще не готов.
Добрый 🖐
Для специфического или конкретного отслеживания, лучше, конечно, дополнять своими сценариями. То есть if (new FileInfo...)
Замерять размер и т.д.
Всем привет!
Зачем ставить запятую, чтоб посмотреть аргументы функции, если есть сочетание клавиш: ctr + shift + пробел?
Нажимайте 3 кнопки вместо 1, Я не против.
а я в FileSystemEventHandler сразу лямбду сую
А почему и зачем у вас 2 рабочих стола? 🤔
Судя по вопросу... их будет очень много. И на все есть ответы, если смотреть плейлист с Урока #0
ruclips.net/p/PL05SB3rBbUsraqiEUeS70RKhVAu97nGeb
@@XpucT вау, так оказывается есть целый плейлист большой, спасибо!
Стыдно признаться, но я совершенно не понял что это было и чего
Если нужно следить за изменением файла.
Тебе такое просто пока не пригождалось наверно.
@@XpucT верно!
Спасибо.