I want to send a file which has been found when the System Watcher has discoverd a created file ending with ".txt", ".doc" or ".docx". My Problem is that the System Watcher discover just files ending with ".txt".
Here is my Code:
private String Attachmenttosend
{
get { return attachmentfile; }
set { attachmentfile = value; }
}
private void NewFileSystemWatcher()
{
String filter = "*.txt,*.doc,*.docx";
string[] FileExtension = filter.Split(',');
for (int i = 0; i < FileExtension.GetLength(0); i++)
{
watcher = new FileSystemWatcher(folder); // on its own Thread
watcher.Created += new FileSystemEventHandler(NewEMail);
attachmenttosend.Add(Attachmenttosend);
watcher.Filter = FileExtension[i];
watcher.EnableRaisingEvents = true;
watchlist.Add(watcher);
}
Send(Attachmenttosend);
}
private void NewEMail(Object source, FileSystemEventArgs e)
{
while (Locked(e.FullPath)) // check if the file is used
{
Thread.Sleep(10);
}
Attachmenttosend = e.FullPath; // store the filename
}
I think this will help you,just create a console app on the fly and paste this in and try it out:
private static string[] filters = new string[] { ".txt", ".doc", ".docx" };
static void Main(string[] args)
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = #"C:\...\...\...";//your directory here
/* Watch for changes in LastAccess and LastWrite times, and
the renaming of files or directories. */
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
//dont set this
//watcher.Filter = "*.txt";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
watcher.EnableRaisingEvents = true;
Console.ReadKey();
}
private static void OnChanged(object source, FileSystemEventArgs e)
{
if(filters.Contains(Path.GetExtension(e.FullPath)))
{
Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
//Attachmenttosend = e.FullPath;
}
}
private static void OnRenamed(object source, RenamedEventArgs e)
{
if (filters.Contains(Path.GetExtension(e.FullPath)))
Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
}
Also as Kunal pointed out
attachmenttosend.Add(Attachmenttosend);
I guess from the uppercase and lower case that you are trying to add to the backing field of the property its own property,dont,also...you dont add to a string only += (concat).
Unless attachmenttosend is a for example a list of strings.
Related
Goal:
The main goal is to get all path names from MySQL, and use File System Watch to watch them paths for rename, deleted and created.
I have this full code here:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using MySql.Data.MySqlClient;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Run();
}
public static void Run()
{
MySqlConnection mcon = new MySqlConnection("credentials");
MySqlDataReader myreader = null;
MySqlCommand cmd = new MySqlCommand("select * from files", mcon);
mcon.Open();
myreader = cmd.ExecuteReader();
List<String> list = new List<String>();
while (myreader.Read())
{
list.Add(myreader[1].ToString());
foreach (string i in list)
{
Console.WriteLine(i);
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = Path.GetDirectoryName($#"{i}");
watcher.Filter = Path.GetFileName($#"{i}");
watcher.EnableRaisingEvents = true;
watcher.IncludeSubdirectories = true;
watcher.Created += directoryChange;
watcher.Deleted += directoryChange;
watcher.Renamed += onRename;
Console.Read();
}
}
mcon.Close();
}
private static void directoryChange(object source, System.IO.FileSystemEventArgs e)
{
Console.WriteLine($"{e.ChangeType} - {e.FullPath} - {System.Environment.NewLine}");
}
private static void onRename(object source, RenamedEventArgs e)
{
Console.WriteLine($"{e.OldFullPath} renamed to {e.FullPath}");
}
}
}
And this is a table in MySQL:
ID Path
1 G:/Folder/EdGzi/Test purposes Python/file.txt
2 G:/Folder/EdGzi/Test purposes Python/test2.txt
Problem:
When I run this application. It watches only 1 file(only the top record only from MySQL data). Whereas, it should have been watching all the files returned from MySQL table.
That's why I have created the foreach code.
Question:
How can I do this?
Get rid of Console.Read from the loop, place it after the loop. That will Console.WriteLine(i); each record from MySQL table.
Like so:
public static void Run()
{
MySqlConnection mcon = new MySqlConnection("server=WINX-PC04;user id=root;password=GS201706;database=technical");
MySqlDataReader myreader = null;
MySqlCommand cmd = new MySqlCommand("select * from files", mcon);
mcon.Open();
myreader = cmd.ExecuteReader();
List<String> list = new List<String>();
while (myreader.Read())
{
list.Add(myreader[1].ToString());
}
mcon.Close();
foreach (string i in list)
{
Console.WriteLine(i);
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = Path.GetDirectoryName($#"{i}");
watcher.Filter = Path.GetFileName($#"{i}");
watcher.EnableRaisingEvents = true;
watcher.IncludeSubdirectories = true;
watcher.Created += directoryChange;
watcher.Deleted += directoryChange;
watcher.Renamed += onRename;
}
Console.Read(); // Likethis
}
You can given FileSystemWatcher objects only one directory and file extension.
You must create multiple FileSystemWatcher objects to monitor multiple different files. If you do this, you must c# lock statement each event.
This example follows the *.jpg extensions, including subdirectories in the target directory.
static void Main(string[] args)
{
// target main folder
string directoryName = #"E:\Apps\2019\SADtest\Decupe\SADtest\Veriler\sources\";
// such as only watch JPG files
string fileExtension = "*.jpg";
using (FileSystemWatcher watcher = new FileSystemWatcher())
{
// NotifyFilter is Flag attribute.
// triggers when file names created, changed or updated.
watcher.NotifyFilter = NotifyFilters.FileName | NotifyFilters.CreationTime | NotifyFilters.LastWrite;
watcher.Path = directoryName;
// the Filter propertie must contain wildcards or empty.
// you cannot write multiple extensions.
// all files : *.*
// only text : *.txt
// ends withs : *test2.txt
watcher.Filter = fileExtension;
// track the same extensions in all subdirectories.
watcher.IncludeSubdirectories = true;
// register events
watcher.Created += Watcher_Created;
watcher.Deleted += Watcher_Deleted;
watcher.Renamed += Watcher_Renamed;
// begin watching...
watcher.EnableRaisingEvents = true;
// sample message
Console.WriteLine("Press 'ENTER' to quit watching.");
Console.WriteLine($"I am watching the files with the '{fileExtension}' extension in the '{directoryName}' directory.");
// wait for the user to quit the program.
Console.WriteLine();
Console.Read();
}
}
private static void Watcher_Renamed(object sender, RenamedEventArgs e)
{
Console.WriteLine($"Renamed:File: {e.OldFullPath} renamed to {e.FullPath}");
}
private static void Watcher_Deleted(object sender, FileSystemEventArgs e)
{
Console.WriteLine($"Deleted:File: {e.FullPath} {e.ChangeType}");
}
private static void Watcher_Created(object sender, FileSystemEventArgs e)
{
Console.WriteLine($"Created:File: {e.FullPath} {e.ChangeType}");
}
Here is the console results :
Press 'ENTER' to quit watching.
I am watching the files with the '*.jpg' extension in the 'E:\Apps\2019\SADtest\Decupe\SADtest\Veriler\sources' directory.
Renamed:File: E:\Apps\2019\SADtest\Decupe\SADtest\Veriler\sources\meee.jpg renamed to E:\Apps\2019\SADtest\Decupe\SADtest\Veriler\sources\sener.jpg
Created:File: E:\Apps\2019\SADtest\Decupe\SADtest\Veriler\sources\logo2.jpg Created
Deleted:File: E:\Apps\2019\SADtest\Decupe\SADtest\Veriler\sources\logo2.jpg Deleted
I have class "SystemWatchFile" used to detect a file change . Every a file changed so i can capture this change in function "OnChanged".
In other loop function i call to SystemWatchFile to monitor the change of file. Like below :
while (true)
{
SystemWatchFile watchfile = new SystemWatchFile(#" f:\Tutorial\C#\FileSytemWatcher\readme.txt");
watchfile.Run();
///at here , how can i get value from "OnChanged" , when a file is changed
}
I try use to delegate to implement callback but not work.My class :
public class SystemWatchFile
{
string FileNeedWatching = "";
bool let = false;
public SystemWatchFile(string file)
{
FileNeedWatching = file;
}
public void Run()
{
using (FileSystemWatcher watcher = new FileSystemWatcher())
{
string filePath1 = FileNeedWatching;
watcher.Path = Path.GetDirectoryName(filePath1);
// Watch for changes in LastAccess and LastWrite times, and
// the renaming of files or directories.
watcher.NotifyFilter = NotifyFilters.LastAccess
| NotifyFilters.FileName
| NotifyFilters.DirectoryName;
// Only watch text files.
watcher.Filter = Path.GetFileName(filePath1);
// Add event handlers.
watcher.Changed += OnChanged;
// Begin watching.
watcher.EnableRaisingEvents = true;
}
}
private void OnChanged(object source, FileSystemEventArgs e)
{
if (let == false)
{
Console.WriteLine($"File: {e.FullPath} {e.ChangeType}");
let = true;
}
else
{
let = false;
}
}
}
How can i get value when file change ?
Is there some mechanism by which I can be notified (in C#) when a file is modified on the disc?
You can use the FileSystemWatcher class.
public void CreateFileWatcher(string path)
{
// Create a new FileSystemWatcher and set its properties.
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = path;
/* Watch for changes in LastAccess and LastWrite times, and
the renaming of files or directories. */
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
// Only watch text files.
watcher.Filter = "*.txt";
// Add event handlers.
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
// Begin watching.
watcher.EnableRaisingEvents = true;
}
// Define the event handlers.
private static void OnChanged(object source, FileSystemEventArgs e)
{
// Specify what is done when a file is changed, created, or deleted.
Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
}
private static void OnRenamed(object source, RenamedEventArgs e)
{
// Specify what is done when a file is renamed.
Console.WriteLine("File: {0} renamed to {1}", e.OldFullPath, e.FullPath);
}
That would be System.IO.FileSystemWatcher.
Use the FileSystemWatcher. You can filter for modification events only.
I have written this code for watching files in my system, but its not alerting any modificationms in the folder or file. How can I achieve this? I am not understanding as it does not show any exceptions or errors.
static void Main(string[] args)
{
FileSystemWatcher();
}
public static void FileSystemWatcher()
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = #"D:\watcher";
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Filter = "*.*";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;
Console.Read();
}
private static void OnChanged(object sender, FileSystemEventArgs e)
{
Console.WriteLine(e.Name + " has changed");
}
I updated the code. The NotifyFilter needs to be expanded if you want to see new files added
static void Main(string[] args)
{
FileSystemWatcher();
}
public static void FileSystemWatcher()
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = #"D:\temp";
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.Filter = "*.*";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += Watcher_Created;
watcher.Renamed += Watcher_Renamed;
watcher.EnableRaisingEvents = true;
Console.Read();
}
private static void Watcher_Renamed(object sender, RenamedEventArgs e)
{
Console.WriteLine(e.Name + " has been renamed");
}
private static void Watcher_Created(object sender, FileSystemEventArgs e)
{
Console.WriteLine(e.Name + " has been added");
}
private static void OnChanged(object sender, FileSystemEventArgs e)
{
Console.WriteLine(e.Name + " has changed");
}
FileSystemWatcher.NotifyFilter Property
watcher.NotifyFilter <- is flag enum!
You need to write:
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
...
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
i like to add controls inside the form1 where a event handler for
watcher.Changed += new FileSystemEventHandler(OnChanged); is defined , is it possible to add control for example list box to the form1 but need to be added inside the event handler where it is defined
/*event added*/
private void btn_start_Click(object sender, EventArgs e)
{
string[] args = {this.txtfolder.Text};
if (args.Length != 1)
{
// Display the proper way to call the program.
Console.WriteLine("Usage: Invalid Operation");
return;
}
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = args[0];
/* Watch for changes in LastAccess and LastWrite times, and
the renaming of files or directories. */
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
// Only watch text files.
watcher.Filter = this.txtfilter.Text;//"*.txt";
// Add event handlers.
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
// watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.Renamed += new RenamedEventHandler(OnRenamed);
// Define the event handlers.
private static void OnChanged(object source, FileSystemEventArgs e)
{
// Specify what is done when a file is changed, created, or deleted.
//Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
// Form1 F ;
// ListBox lst = new ListBox();
//lst.Items.Add("File: " + e.FullPath + " " + e.ChangeType.ToString());
//f.lsttracker.Items.Add("File: " + e.FullPath + " " + e.ChangeType.ToString());
// F.controls.Add(lst);
This is what your looking for. From what you commented out, you probably didn't set the location and size, thus adding the control probably wasn't working. But you should really make sure to regulate this and make sure you are only adding controls exactly when you want to and no more.
private static void OnChanged(object source, FileSystemEventArgs e)
{
ListBox toAdd = new ListBox();
toAdd.Location = new Point(20,20);
toAdd.Size = new Size(200,200);
this.Controls.Add(toAdd);
}
If you want to store the controls you added, try something like this:
private List<Control> AddedItems = new List<Controls>();
private int OffsetY = 0;
private static void OnChanged(object source, FileSystemEventArgs e)
{
ListBox toAdd = new ListBox();
if(AddedItem.Last().Point.Y == OffsetY) // just an example of reusing previously added items.
{
toAdd.Location = new Point(20, OffsetY);
toAdd.Size = new Size(200,200);
AddedItems.Add(toAdd);
this.Controls.Add(toAdd);
}
OffsetY += 200;
}
EDIT: In reply to what you mentioned in the comment below.
[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
private void btn_start_Click(object sender, EventArgs e)
{
string FolderPath = this.txtfolder.Text;
string Filter = this.txtfilter.Text;
if(!Directory.Exists(FolderPath))
{
Console.WriteLine("Not a valid directory"); //checks directory is valid
return;
}
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = FolderPath;
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
// Only watch filter files.
watcher.Filter = Filter;
watcher.IncludeSubdirectories = true; //monitor subdirectories?
watcher.EnableRaisingEvents = true; //allows for changed events to be fired.
// Add event handlers.
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created += new FileSystemEventHandler(OnChanged);
}
//Delegate to get back to UI thread since OnChanged fires on non-UI thread.
private delegate void updateListbox(string context);
private void OnChanged(object source, FileSystemEventArgs e)
{
this.Invoke(new updateListbox(UpdateListbox), "File: " + e.Name);
this.Invoke(new updateListbox(UpdateListbox), ">>Action: " + e.ChangeType);
this.Invoke(new updateListbox(UpdateListbox), ">>Path: " + e.FullPath);
}
public void UpdateListbox(string context)
{
lsttracker.Items.Add(context);
}