Below is my code, I am running a windows service, but if i kept ideal for long time 5 or 6 days after that it stops firing events. though my service is running.Please help me on this
private FileSystemWatcher watcher = new FileSystemWatcher();
public bool StartFileWatcher()
{
_logger.Info("StartFileWatcher File watcher started");
if (string.IsNullOrEmpty(_fileWatcherTargetPath))
{
_logger.Error("StartFileWatcher Directory name is null or Empty");
return false;
}
DirectoryInfo dir = new DirectoryInfo(_fileWatcherTargetPath);
if (!Directory.Exists(_fileWatcherTargetPath))
{
_logger.Info("StartFileWatcher Directory Created " + _fileWatcherTargetPath);
Directory.CreateDirectory(_fileWatcherTargetPath);
}
//Add folder path to file watcher
watcher.Path = _fileWatcherTargetPath;
watcher.IncludeSubdirectories = true;
//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;
// Add event handlers.
watcher.Created += new FileSystemEventHandler(OnChanged);
// Begin watching.
watcher.EnableRaisingEvents = true;
GC.KeepAlive(watcher);
SetTimer();
return true;
}
Related
I have created a Windows Service which uses a FileSystemWatcher to look for changes in different directories. When I launch the service I am getting the error:
Error 1053:The service did not respond to start or control request in timely fashion.
I think that the error is coming from an infinite loop caused by using the using statement in the Watch() method as shown below:
public FileSystemWatcher Watch()
{
FileSystemWatcher watcher;
using (watcher = new FileSystemWatcher($"C:\\Users\\lashi\\AppData\\Roaming\\Sublime Text 3", _ext))
{
watcher.NotifyFilter = NotifyFilters.LastAccess
| NotifyFilters.LastWrite
| NotifyFilters.FileName
| NotifyFilters.DirectoryName;
watcher.IncludeSubdirectories = true;
// Add event handlers.
watcher.Changed += OnChanged;
watcher.Created += OnChanged;
watcher.Deleted += OnChanged;
watcher.Renamed += OnRenamed;
// Begin watching.
watcher.EnableRaisingEvents = true;
}
return watcher;
}
This is my OnStart() method:
protected override void OnStart(string[] args)
{
String userName;
String expt;
if (args.Length < 2)
{
Console.WriteLine($"FileWatcher <user> <exptName>");
Console.WriteLine($"Captures files into /temp/<exptName>-log and /temp/<exptName>-files");
userName = "wost";
expt = "expt1";
}
else
{
userName = args[0];
expt = args[1];
}
String lexpt = $"C:\\Users\\lashi\\Desktop\\EMMC_CACHE\\{expt}-log";
String fexpt = $"C:\\Users\\lashi\\Desktop\\EMMC_CACHE\\{expt}-file";
if (!Directory.Exists(fexpt))
{
Directory.CreateDirectory(fexpt);
}
if (!Directory.Exists(lexpt))
{
Directory.CreateDirectory(lexpt);
}
// File Watcher Launch
Watcher w = new Watcher(lexpt, fexpt, userName);
FileSystemWatcher fw = w.Watch();
}
Can you please help me to find a solution to this issue? I have tried a lot of suggestions but they don't seem to work. Thank you!
Click here! to see how to increase Windows services pipe timeout by editing the registry keys
I am trying to detect when a file is being removed from a folder in my drive. Upon detection, I want to write code that does something. Is there an event handler for this kind of 'event' in C#? Looked around but couldn't find any. Is it even possible?
You can use FileSystemWatcher to monitor a directory, and subscribe to it's Deleted event. See the code below
static void Main(string[] args)
{
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = "C:/some/directory/to/watch";
watcher.NotifyFilter = NotifyFilters.LastAccess |
NotifyFilters.LastWrite |
NotifyFilters.FileName |
NotifyFilters.DirectoryName;
watcher.Filter = "*.*";
watcher.Deleted += new FileSystemEventHandler(OnDeleted);
watcher.EnableRaisingEvents = true;
}
private static void OnDeleted(object sender, FileSystemEventArgs e)
{
throw new NotImplementedException();
}
I have a console app that need to monitor a specific directory and wait for all files to be deleted for a specific amount of time.
If after that time has exceeded and all of the files has not been deleted yet, I need the program to throw an exception. How can I accomplish this?
public static void FileWatcher(string fileName, int timeToWatch)
{
FileSystemWatcher watcher = new FileSystemWatcher();
try
{
watcher.Path = myPath;
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.Filter = string.Format("*{0}*", fileName);
watcher.Deleted += new FileSystemEventHandler(OnChanged);
watcher.EnableRaisingEvents = true;
}
catch
{
throw;
}
}
You can use Task.Delay to setup a timeout (I assume timeToWatch is in milliseconds, if not then change it accordingly). If the directory has no more files (not checking subfolders) then it sets the other task as completed. The method will block (WaitAny) until either the timeout occurs or the files are all deleted. This can easily be changed to be async if required.
public static void FileWatcher(string fileName, int timeToWatch)
{
FileSystemWatcher watcher = new FileSystemWatcher();
var timeout = Task.Delay(timeToWatch);
var completedTcs = new TaskCompletionSource<bool>();
watcher.Path = myPath;
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.Filter = string.Format("*{0}*", fileName);
watcher.Deleted += (s, e) => OnChanged(myPath, timeout, completedTcs);
watcher.EnableRaisingEvents = true;
OnChanged(myPath, timeout, completedTcs);
// Wait for either task to complete
var completed = Task.WaitAny(completedTcs.Task, timeout);
// Clean up
watcher.Dispose();
if (completed == 1)
{
// Timed out
throw new Exception("Files not deleted in time");
}
}
public static void OnChanged(string path, Task timeout, TaskCompletionSource<bool> completedTcs)
{
if (!Directory.GetFiles(path).Any())
{
// All files deleted (not recursive)
completedTcs.TrySetResult(true);
}
}
I'd like to continuously read in all image files from a folder on my local drive, then do some processing and end the program once all images have been read. The images numbers are not sequential they are random however they are located in a single folder. Currently my program can only read in one file; see code below
string imagePath = Path.Combine(Freconfig.GetSamplesFolder(), "24917324.jpg");
use FileSystemWatcher
https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx
FileSystemWatcher watcher = new FileSystemWatcher();
watcher.Path = Freconfig.GetSamplesFolder();
watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite
| NotifyFilters.FileName | NotifyFilters.DirectoryName;
watcher.Filter = "*.jpg";
// 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;
before starting watcher, use directorylisting to find all existing files and process them, then use watcher
Is this what you are looking for? Directory.GetFiles(#"..\somepath") (MSDN)
You could try:
directoryInfo = new DirectoryInfo("C:/YOUR/DIRECTORY/HERE]");
var files = directoryInfo.GetFiles("*.jpg").OrderBy(x => x.CreationTimeUtc);
foreach (var file in files)
{
//Your processing
}
Note this will get all the .jpg files in a directory. The foreach loop will start with the oldest files first.
This should get all the files in a directory:
private List<FileInfo> GetFileInfo()
{
string path = #"C:\MyPath";
List<FileInfo> files = new List<FileInfo>();
DirectoryInfo di = new DirectoryInfo(path);
//TopDirectoryOnly if you don't want subfolders
foreach (FileInfo f in di.GetFiles("*.jpg", SearchOption.TopDirectoryOnly))
{
files.Add(f);
}
return files;
}
Then in your code, iterate over the returned collection and do whatever work you need to do with them.
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.