I have a hidden share:
\\computername\Logs$
And I need to monitor file changes in that share.
I've decided to use FileSystemWatcher Class, but it doesn't raise any events. And it doesn't show any errors to me.
static void Main(string[] args)
{
FileWatcher fw = new FileWatcher(#"\\computername\Logs$", "*.*");
fw.Start();
}
class FileWatcher(string filePath, string mask)
{
FileSystemWatcher watcher;
watcher.Path = filePath;
watcher.Filter = mask;
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.Changed += Watcher_Changed;
watcher.Error += OnError;
public void Start()
{
watcher.InternalBufferSize = 64 * 1024;
watcher.EnableRaisingEvents = true;
Console.WriteLine("Watcher Started");
while (!Console.KeyAvailable)
{
Thread.Sleep(1000);
}
}
private void Watcher_Changed(object sender, FileSystemEventArgs e)
{
Console.WriteLine("File Changed");
}
private void OnError(object sender, ErrorEventArgs e)
{
Console.WriteLine("Error");
}
}
Does FileSystemWatcher work properly with hidden shares?
This code will not compile ,maybe you had errors while copy the code
and where the event handler Watcher_Changed, maybe you have mistake and put Watcher_Created instead
Related
I am reading directories and adding .ini files to listbox1 or lisbox2 depending what is inside.
private void Form1_Load(object sender, EventArgs e)
{
string rootdir = #"C:\Users\isaced1\Desktop\test"; //root directory of all projects
string[] files = Directory.GetFiles(rootdir, "*.ini", SearchOption.AllDirectories); //searches for specific .ini files in all directories whithin rood directory
//cycles through all .ini files and adds it to lsitbox1 or listbox2
foreach (string item in files)
{
string fileContents = File.ReadAllText(item); //reads all .ini files
const string PATTERN = #"OTPM = true"; //search pattern in .ini files
Match match = Regex.Match(fileContents, PATTERN, RegexOptions.IgnoreCase); //matches pattern with content in .ini file
if (match.Success)
{
listBox1.Items.Add(item); //if match is successfull places file in lisbox1
listBox1.ForeColor = Color.Green;
}
else
{
listBox2.Items.Add(item); //if match is unsuccessfull places file in lisbox2
listBox2.ForeColor = Color.Red;
}
}
}
Now I want to to continuously repeat the process. I tried to do timer, but I keep getting error "error CS0120: An object reference is required for the non-static field, method, or property". I understand that my private void Form1_Load has to be static, but I just dont know way around it.
My timer code
private static System.Timers.Timer aTimer;
public static void Main1()
{
// Create a timer and set a two second interval.
aTimer = new System.Timers.Timer();
aTimer.Interval = 1000;
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += new ElapsedEventHandler(Form1_Load);
// Have the timer fire repeated events (true is the default)
aTimer.AutoReset = true;
// Start the timer
aTimer.Enabled = true;
}
Any suggestions, thanks.
Don't poll for new files (using a timer is inefficient), use events from the OS to tell you when files are created/updated/deleted etc.
https://learn.microsoft.com/en-us/dotnet/api/system.io.filesystemwatcher?view=net-6.0
static void Main()
{
using var watcher = new FileSystemWatcher(#"C:\path\to\folder");
watcher.NotifyFilter = NotifyFilters.Attributes
| NotifyFilters.CreationTime
| NotifyFilters.DirectoryName
| NotifyFilters.FileName
| NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.Security
| NotifyFilters.Size;
watcher.Changed += OnChanged;
watcher.Created += OnCreated;
watcher.Deleted += OnDeleted;
watcher.Renamed += OnRenamed;
watcher.Error += OnError;
watcher.Filter = "*.txt";
watcher.IncludeSubdirectories = true;
watcher.EnableRaisingEvents = true;
Console.WriteLine("Press enter to exit.");
Console.ReadLine();
}
private static void OnChanged(object sender, FileSystemEventArgs e)
{
if (e.ChangeType != WatcherChangeTypes.Changed)
{
return;
}
Console.WriteLine($"Changed: {e.FullPath}");
}
private static void OnCreated(object sender, FileSystemEventArgs e)
{
string value = $"Created: {e.FullPath}";
Console.WriteLine(value);
}
private static void OnDeleted(object sender, FileSystemEventArgs e) =>
Console.WriteLine($"Deleted: {e.FullPath}");
private static void OnRenamed(object sender, RenamedEventArgs e)
{
Console.WriteLine($"Renamed:");
Console.WriteLine($" Old: {e.OldFullPath}");
Console.WriteLine($" New: {e.FullPath}");
}
private static void OnError(object sender, ErrorEventArgs e) =>
PrintException(e.GetException());
private static void PrintException(Exception? ex)
{
if (ex != null)
{
Console.WriteLine($"Message: {ex.Message}");
Console.WriteLine("Stacktrace:");
Console.WriteLine(ex.StackTrace);
Console.WriteLine();
PrintException(ex.InnerException);
}
}
I am trying to determine when my SQL Server log file changes.
I wrote a simple program:
static class Program
{
static void Main(string[] args)
{
try
{
var logDirectory = #"C:\Program Files\Microsoft SQL Server\MSSQL15.MSSQLSERVER\MSSQL\Log";
using var watcher = new FileSystemWatcher(logDirectory);
watcher.NotifyFilter = NotifyFilters.Attributes
| NotifyFilters.CreationTime
| NotifyFilters.DirectoryName
| NotifyFilters.FileName
| NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.Security
| NotifyFilters.Size;
watcher.Changed += OnChanged;
//watcher.Created += OnCreated;
//watcher.Deleted += OnDeleted;
//watcher.Renamed += OnRenamed;
watcher.Error += OnError;
watcher.Filter = "ERRORLOG.*";
watcher.IncludeSubdirectories = false;
watcher.EnableRaisingEvents = true;
while (true)
{
// Empty Loop
}
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
private static void OnError(object sender, ErrorEventArgs e)
{
Console.WriteLine("Error in watcher.");
}
private static void OnChanged(object sender, FileSystemEventArgs e)
{
Console.WriteLine("ErrorLog has changed.");
}
}
I get no errors in the debug window and no output in the console. While it is running, I log in with SSMS. I check the directory and both the ERRORLOG file size and modified date have changed. Any help will be appreciated.
I'm setting a file a newName at runtime "rename " context menu strip item clicked and want to FileSystemWatcher.Renamed Event function properly
I'm trying to make File Explorer in c# window form
private void renameToolStripMenuItem_Click(object sender, EventArgs e)
{
FileSystemWatcher watcher = new FileSystemWatcher(path_textBox.Text);
//the renaming of files or directories.
watcher.NotifyFilter = NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.FileName
| NotifyFilters.DirectoryName;
watcher.Renamed += new RenamedEventHandler(OnRenamed);
watcher.Error += new ErrorEventHandler(OnError);
watcher.EnableRaisingEvents = true;
}
private static void OnRenamed(object source, RenamedEventArgs e)
{
// Show that a file has been renamed.
WatcherChangeTypes wct = e.ChangeType;
MessageBox.Show($"File: {e.OldFullPath} renamed to {e.FullPath}");
}
In renameToolStripMenuItem_Click event OnRenamed event is not running after calling
You're FileSystemWatcher (FSW) is configured correctly, but you're not renaming the file and thereby the FSW isn't raising the OnRename event. Here is a quickly thrown together example that should work:
class YourClass
{
private FileSystemWatcher _watcher;
// You want to only once initialize the FSW, hence we do it in the Constructor
public YourClass()
{
_watcher = new FileSystemWatcher(path_textBox.Text);
//the renaming of files or directories.
watcher.NotifyFilter = NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.FileName
| NotifyFilters.DirectoryName;
watcher.Renamed += new RenamedEventHandler(OnRenamed);
watcher.Error += new ErrorEventHandler(OnError);
watcher.EnableRaisingEvents = true;
}
private void renameToolStripMenuItem_Click(object sender, EventArgs e)
{
// Replace 'selectedFile' and 'newFilename' with the variables
// or values you want (probably from the GUI)
System.IO.File.Move(selectedFile, newFilename);
}
private void OnRenamed(object sender, RenamedEventArgs e)
{
// Do whatever
MessageBox.Show($"File: {e.OldFullPath} renamed to {e.FullPath}");
}
// Missing the implementation of the OnError event handler
}
I have this code, which should keep richTextBox2 updated at all times with usedPath's contents, but it doesn't.
private void watch()
{
var usedPath = Path.Combine(Directory.GetCurrentDirectory(), "usedwords.txt");
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = usedPath;
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Filter = "*.txt*";
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;
}
private void OnChanged(object source, FileSystemEventArgs e)
{
string usedPath = Path.Combine(Directory.GetCurrentDirectory(), "usedwords.txt");
richTextBox2.LoadFile(usedPath, RichTextBoxStreamType.PlainText);
}
Can someone help me figure out what I have wrong?
Problem 1: Your watcher.Path = path of a single file, which will cause error.
Solution: Look at this: Use FileSystemWatcher on a single file in C#
watcher.Path = Path.GetDirectoryName(filePath1);
watcher.Filter = Path.GetFileName(filePath1);
Problem 2: Accessing richTextBox2 in OnChanged() will cause cross-thread error
Solution: Use this:
private void OnChanged(object source, FileSystemEventArgs e)
{
Invoke((MethodInvoker)delegate
{
string usedPath = Path.Combine(Directory.GetCurrentDirectory(), "usedwords.txt");
richTextBox2.LoadFile(usedPath, RichTextBoxStreamType.PlainText);
});
}
Problem 3: There may be error when trying to LoadFile while some other programs are writing to it.
(Possible) Solution: Put a Thread.Sleep(10) in before trying to LoadFile in OnChanged
private void OnChanged(object source, FileSystemEventArgs e)
{
Thread.Sleep(10);
Invoke((MethodInvoker)delegate
{
richTextBox1.LoadFile(usedPath, RichTextBoxStreamType.PlainText);
});
}
My complete code:
public partial class Form1 : Form
{
string usedPath = #"C:\Users\xxx\Desktop\usedwords.txt";
public Form1()
{
InitializeComponent();
watch();
}
private void watch()
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = Path.GetDirectoryName(usedPath);
watcher.Filter = Path.GetFileName(usedPath);
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;
}
private void OnChanged(object source, FileSystemEventArgs e)
{
Thread.Sleep(10);
Invoke((MethodInvoker)delegate
{
richTextBox1.LoadFile(usedPath, RichTextBoxStreamType.PlainText);
});
}
}
I am trying to monitor a directory for new files in it with the FileSystemWatcher Class.
My Problem is that the event doesn't get triggered. My watcher class is:
public class Filewatcher
{
private FileSystemWatcher watcher;
public Filewatcher(string path, string filefilter)
{
this.watcher = new FileSystemWatcher();
this.watcher.Path = path;
this.watcher.NotifyFilter = NotifyFilters.FileName; //| NotifyFilters.LastWrite | NotifyFilters.LastAccess
this.watcher.Filter = filefilter;
this.watcher.Created += new FileSystemEventHandler(OnChanged);
}
public void start_watching()
{
//this.watcher.IncludeSubdirectories = true;
this.watcher.EnableRaisingEvents = true;
Console.WriteLine("Press Enter to quit\r\n");
Console.ReadLine();
}
private static void OnChanged(object source, FileSystemEventArgs e)
{
//FileInfo objFileInfo = new FileInfo(e.FullPath);
//if (!objFileInfo.Exists) return;
Console.WriteLine("got the change\r\n");
global_functions.perform_action(Global_Vars.thereader.read(e.FullPath), Global_Vars.thepattern);
}
}
Operating System is Win 7 Prof x64
You don't make a call to start_watching(). Add a call to that and it may work better.