To send bulk email in my web application I am using filewatcher to send the application.
I have planned to write filewatcher with the console application instead of windows service or scheduler.
I have copied the executable file shortcut in the following path.
%appdata%\Microsoft\Windows\Start Menu\Programs
Ref: https://superuser.com/questions/948088/how-to-add-exe-to-start-menu-in-windows-10
After run the executable file the file watcher is not watched always.
After searching some sites, i have found that we need to add the code
new System.Threading.AutoResetEvent(false).WaitOne();
Is this the right method to add in the executable file and to watch the folder?
After run the console application (without above code) is the file won't be watched always?
What will be the right method to use the file watcher?
FileSystemWatcher watcher = new FileSystemWatcher();
string filePath = ConfigurationManager.AppSettings["documentPath"];
watcher.Path = filePath;
watcher.EnableRaisingEvents = true;
watcher.NotifyFilter = NotifyFilters.FileName;
watcher.Filter = "*.*";
watcher.Created += new FileSystemEventHandler(OnChanged);
Since it's a Console Application you need to write a code in the Main method to wait and not to close immediately after running codes.
static void Main()
{
FileSystemWatcher watcher = new FileSystemWatcher();
string filePath = ConfigurationManager.AppSettings["documentPath"];
watcher.Path = filePath;
watcher.EnableRaisingEvents = true;
watcher.NotifyFilter = NotifyFilters.FileName;
watcher.Filter = "*.*";
watcher.Created += new FileSystemEventHandler(OnChanged);
// wait - not to end
new System.Threading.AutoResetEvent(false).WaitOne();
}
Your code only tracks changes in the root folder, if you wanted to watch the subfolders you need to set IncludeSubdirectories=true for your watcher object.
static void Main(string[] args)
{
FileSystemWatcher watcher = new FileSystemWatcher();
string filePath = #"d:\watchDir";
watcher.Path = filePath;
watcher.EnableRaisingEvents = true;
watcher.NotifyFilter = NotifyFilters.FileName;
watcher.Filter = "*.*";
// will track changes in sub-folders as well
watcher.IncludeSubdirectories = true;
watcher.Created += new FileSystemEventHandler(OnChanged);
new System.Threading.AutoResetEvent(false).WaitOne();
}
You must also be aware of buffer overflow. FROM MSDN FileSystemWatcher
The Windows operating system notifies your component of file changes
in a buffer created by the FileSystemWatcher. If there are many
changes in a short time, the buffer can overflow. This causes the
component to losing track of changes in the directory, and it will only
provide the blanket notification. Increasing the size of the buffer with
the InternalBufferSize property is expensive, as it comes from
non-paged memory that cannot be swapped out to disk, so keep the
buffer as small yet large enough to not miss any file change events.
To avoid a buffer overflow, use the NotifyFilter and
IncludeSubdirectories properties so you can filter out unwanted change
notifications.
Related
I would like to be able to run commands on the command prompt on a windows pc from an Android phone.
I am currently doing it by a wpf app on windows which listens for files with .dev in their file name.
This method is very annoying to use on a phone as I have to type out the command in a .bat file and then copy the file to D:\Shared using an app like File Manager to transfer the file via windows share
using Microsoft.Win32;
using System.Diagnostics;
namespace Dev
{
public partial class Dev : ApplicationContext
{
class Var
{
public static string temp = Path.GetTempPath();
}
public Dev()
{
RegistryKey key = Registry.CurrentUser.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce", true);
key.SetValue("Remote Dev", Application.ExecutablePath);
// Create a new FileSystemWatcher and set its properties.
FileSystemWatcher watcher = new()
{
Path = "D:\\Shared",
/* Watch for changes in LastAccess and LastWrite times, and
the renaming of files or directories. */
NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName,
// Only watch text files.
Filter = "*.dev.*"
};
// Add event handlers.
watcher.Created += new FileSystemEventHandler(Create);
// Begin watching.
watcher.EnableRaisingEvents = true;
//This method is called when a file is created.
static void Create(object source, FileSystemEventArgs e)
{
string tempPath = Var.temp + Path.GetFileName(e.FullPath);
if (File.Exists(tempPath)) File.Delete(tempPath);
File.Move(e.FullPath, tempPath);
Thread.Sleep(1000);
Process.Start("explorer", tempPath);
}
}
}
}
I would like to create an app that can automate the process of creating the .bat file and coping it to the D:\Shared without the need of any third party app.
! Please help me in the Maui part as I am new to it.
Thanks
I am watching for changes in a .log file that is being written by a software of an industrial machine.
The software is continously writing but no changes are detected by FileSystemWatcher.
However, when I open the Windows Explorer and navigate to the watched directory, suddenly FileSystemWatcher detects inmmediatly the last change and fires. (quite strange).
I am configuring the watcher as:
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = "C:\\nextgen\\log";
watcher.NotifyFilter = NotifyFilters.DirectoryName |
NotifyFilters.LastAccess |
NotifyFilters.LastWrite |
NotifyFilters.FileName |
NotifyFilters.Size |
NotifyFilters.Attributes | NotifyFilters.CreationTime;
// Only watch logfiles.
watcher.Filter = "*.log";
// Add event handlers.
watcher.Changed += new FileSystemEventHandler(OnChanged);
watcher.Created+= new FileSystemEventHandler(OnChanged);
// Begin watching.
watcher.EnableRaisingEvents = true;
I am running a filesystemwatcher on the "w3svc1" folder, where the iis logs are stored by default. When I go to the adress localhost or anyone of my webapp localhost/xxxxx. The filesystemwatcher does not raise events. I know that there is a delay between the request and the writting in the logs, but even after one hour there is no change event raised. But then, when I open the file with notepad++, I see the logs added. Is anyone has an explaination. This is my code:
class Program
{
static void Main(string[] args)
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = #"C:\inetpub\logs\LogFiles\W3SVC1";
watcher.NotifyFilter = NotifyFilters.LastWrite;
watcher.IncludeSubdirectories = true;
watcher.Filter = "*.log";
watcher.Changed += new FileSystemEventHandler(OnChangedok);
watcher.Created += new FileSystemEventHandler(OnChangedok);
watcher.EnableRaisingEvents = true;
Console.WriteLine("Press \'q\' to quit the sample.");
while (Console.Read() != 'q') ;
}
private static void OnChangedok(object source, FileSystemEventArgs e)
{
Console.WriteLine(e.FullPath);
}
This is because IIS open stream and write the logs into file but didn't flush the changes Immediately. When you open the file in notepad++, it access this file which trigger the file modification event . Please refer this thread also.
For some reason, my FileSystemWatcher is not firing any events whatsoever. I want to know any time a new file is created, deleted or renamed in my directory. _myFolderPath is being set correctly, I have checked.
Here is my current code:
public void Setup() {
var fileSystemWatcher = new FileSystemWatcher(_myFolderPath);
fileSystemWatcher.NotifyFilter = NotifyFilters.LastAccess |
NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
fileSystemWatcher.Changed += FileSystemWatcherChanged;
fileSystemWatcher.Created += FileSystemWatcherChanged;
fileSystemWatcher.Deleted += FileSystemWatcherChanged;
fileSystemWatcher.Renamed += FileSystemWatcherChanged;
fileSystemWatcher.Filter = "*.*";
fileSystemWatcher.EnableRaisingEvents = true;
}
private void FileSystemWatcherChanged(object sender, FileSystemEventArgs e)
{
MessageBox.Show("Queue changed");
listBoxQueuedForms.Items.Clear();
foreach (var fileInfo in Directory.GetFiles(_myFolderPath, "*.*", SearchOption.TopDirectoryOnly))
{
listBoxQueuedForms.Items.Add(fileInfo));
}
}
You seem to be creating the FileSystemWatcher as a local variable in the setup method. This will of course go out of scope at the end of the method and may well be getting tidied up at that point, thus removing the watches.
Try creating the FSW at a point where it will be persisted (eg a program level variable) and see if that sorts you out.
My problem was that I expected certain actions to cause the FileSystemWatcher Changed event to fire. For example, moving a file (clicking and dragging) from the desktop to the watched location did not raise an event but copying an existing file and pasting a new copy of it (there by creating a new file to the file system and not simply moving an existing one) caused the Changed event to be raised.
My solution was to add every NotifyFilter to my FileSystemWatcher. This way I am notified in all cases where the FileSystemWatcher is able to notify me.
NOTE that it isn't entirely intuitive/obvious as to which filters will notify you for specific cases. For example, I expected that if I included FileName that I would be notified of any changes to an existing file's name...instead Attributes seem to handle that case.
watcher.NotifyFilter = NotifyFilters.Attributes |
NotifyFilters.CreationTime |
NotifyFilters.FileName |
NotifyFilters.LastAccess |
NotifyFilters.LastWrite |
NotifyFilters.Size |
NotifyFilters.Security;
Use this setter to enable the trigger:
watcher.EnableRaisingEvents = true;
My issue was that I expected it watches subdirectories also but it doesn't do it by default. If you would like to monitor also subdirectories then set IncludeSubdirectories property to true (it's false by default):
fileSystemWatcher.IncludeSubdirectories = true;
We just had a very similar problem, where moving a folder did not trigger the expected events. The solution was to hard copy the entire folder, rather than just moving it.
DirectoryCopy(".", ".\\temp", True)
Private Shared Sub DirectoryCopy( _
ByVal sourceDirName As String, _
ByVal destDirName As String, _
ByVal copySubDirs As Boolean)
' Get the subdirectories for the specified directory.
Dim dir As DirectoryInfo = New DirectoryInfo(sourceDirName)
If Not dir.Exists Then
Throw New DirectoryNotFoundException( _
"Source directory does not exist or could not be found: " _
+ sourceDirName)
End If
Dim dirs As DirectoryInfo() = dir.GetDirectories()
' If the destination directory doesn't exist, create it.
If Not Directory.Exists(destDirName) Then
Directory.CreateDirectory(destDirName)
End If
' Get the files in the directory and copy them to the new location.
Dim files As FileInfo() = dir.GetFiles()
For Each file In files
Dim temppath As String = Path.Combine(destDirName, file.Name)
file.CopyTo(temppath, False)
Next file
' If copying subdirectories, copy them and their contents to new location.
If copySubDirs Then
For Each subdir In dirs
Dim temppath As String = Path.Combine(destDirName, subdir.Name)
DirectoryCopy(subdir.FullName, temppath, true)
Next subdir
End If
End Sub
I am using the FileSystemWatcher to notify when the new files gets created in the network directory. We process the text files(about 5KB size) and delete them immediately when the new file gets created in the directory. If the FileSystemWatcher windows service stops for some reason we have to look for the unprocessed files after it gets back up and running. How can I handle if the new file comes while processing the old files from the directory? Any examples please?
Thank you,
Here is the code example I have with simple form.
public partial class Form1 : Form
{
private System.IO.FileSystemWatcher watcher;
string tempDirectory = #"C:\test\";
public Form1()
{
InitializeComponent();
CreateWatcher();
GetUnprocessedFiles();
}
private void CreateWatcher()
{
//Create a new FileSystemWatcher.
watcher = new FileSystemWatcher();
watcher.Filter = "*.txt";
watcher.NotifyFilter = NotifyFilters.FileName;
//Subscribe to the Created event.
watcher.Created += new FileSystemEventHandler(watcher_FileCreated);
watcher.Path = #"C:\test\";
watcher.EnableRaisingEvents = true;
}
void watcher_FileCreated(object sender, FileSystemEventArgs e)
{
//Parse text file.
FileInfo objFileInfo = new FileInfo(e.FullPath);
if (!objFileInfo.Exists) return;
ParseMessage(e.FullPath);
}
void ParseMessage(string filePath)
{
// Parse text file here
}
void GetUnprocessedFiles()
{
// Put all txt files into array.
string[] array1 = Directory.GetFiles(#"C:\test\");
foreach (string name in array1)
{
string path = string.Format("{0}{1}", tempDirectory, name)
ParseMessage(path);
}
}
}
When the process starts do the following:
first get the contents of the folder
process every file (end delete them as you already do now)
repeat until no files are in the folder (check again here, since a new file could have been placed in the folder).
start the watcher
For any of our services that use the FileSystemWatcher we always process all the files that exist in the directory first, prior to starting the watcher. After the watcher has been started we then start a timer (with a fairly long interval) to handle any files that appear in the directory without triggering the watcher (it does happen from time to time). That usually covers all the possibilities.