mmunger
asked on
C# Service FileSystemwatcher isse
I had this question after viewing Windows Service- File Watcher.
I am working on an application that monitors a folder and triggers a procedure to parse a file when a new file is saved to the folder. My current application works for only one file and then it does not fire the procedure again. I need it to fire the changed event everytime a new file is saved to that folder. My service continues to run and it doesn't log anything so it doesn't seem to be catching errors. Attached is the source code for my service. Any help would be appreciated.
Thanks,
@CreativeTechie
I am working on an application that monitors a folder and triggers a procedure to parse a file when a new file is saved to the folder. My current application works for only one file and then it does not fire the procedure again. I need it to fire the changed event everytime a new file is saved to that folder. My service continues to run and it doesn't log anything so it doesn't seem to be catching errors. Attached is the source code for my service. Any help would be appreciated.
Thanks,
@CreativeTechie
You haven't attached the code
ASKER
My bad
public partial class IKONEDD : ServiceBase
{
public FileSystemWatcher watcher;
//Constants used in IKONEDD service
#region Constants
public const string MyServiceName = "IKONEDDSERV";
//private FileSystemWatcher watcher;
//X3 destination of pdf on X3 application Server
private static string TempDirectory = ConfigurationManager.AppSettings.Get("TempDirectory");
//directory used to parse pdf document
private static string ParseDir = ConfigurationManager.AppSettings.Get("ParseDirectory");
//email address where diagnostic report is sent
private static string diagEmail = ConfigurationManager.AppSettings.Get("Diagnostic Email");
//X3 Folder that the solution is pulling from
private static string X3Folder = ConfigurationManager.AppSettings.Get("X3Folder");
//email address set for emails sent
private static string documentEmailFrom = ConfigurationManager.AppSettings.Get("Email From");
#endregion
public IKONEDD()
{
InitializeComponent();
}
//Actions associated with IKONEDD service
#region Service Methods
//Runs when service starts
protected override void OnStart(string[] args)
{
try
{
Directory.CreateDirectory(ParseDir);
Directory.CreateDirectory(TempDirectory);
watcher = new FileSystemWatcher(TempDirectory, "*.pdf");
Directory.SetCurrentDirectory(TempDirectory);
watcher.Created += new FileSystemEventHandler(OnChanged);
}
catch (Exception e)
{
LogEvent(e.Message);
sendDiagnosticWError(e.Message);
}
finally
{
Directory.SetCurrentDirectory(TempDirectory);
watcher.EnableRaisingEvents = true;
}
}
protected override void OnStop()
{
try
{
LogEvent("Service Stopped");
watcher.EnableRaisingEvents = false;
watcher.Dispose();
}
catch (Exception g)
{
LogEvent("Error:" + g.Message);
}
}
protected override void OnPause()
{
Directory.SetCurrentDirectory(TempDirectory);
watcher.EnableRaisingEvents = false;
}
protected override void OnContinue()
{
Directory.SetCurrentDirectory(TempDirectory);
watcher.EnableRaisingEvents = true;
}
ASKER
Here is the OnChange that is supposed to run when FileWatcher detects a new file in the temp directory:
public static void OnChanged(object source, FileSystemEventArgs e)
{
//Wait for file to be created
FileInfo readingFile = new FileInfo(e.Name);
while (IsFileLocked(readingFile)) { };
//set the current directory
Directory.SetCurrentDirectory(TempDirectory);
PDFParser parsePDF = new PDFParser();
int batchNum = 0;
string outputFile = "text.txt";
parsePDF.ExtractText(e.Name, outputFile);
string fileType = getDocType(e.Name);
List<LogRow> log = new List<LogRow>();
if (parsePDF.errorFlag == true)
{
LogEvent(parsePDF.error.Message);
sendDiagnosticWError(parsePDF.error.Message);
}
else if (parsePDF.listOfDocs.Count == 0)
{
LogEvent("Number of documents returned is < 0. Please check Crystal Report for special string required for parsing.");
sendDiagnosticWError("Number of documents returned is < 0. Please check Crystal Report for special string required for parsing.");
}
else
{
Batch batchOfDocs = new Batch();
batchOfDocs.NumberOfDocs = parsePDF.listOfDocs.Count;
batchOfDocs.Type = fileType;
batchOfDocs.createBatch();
//set batchNumber for log email
batchNum = batchOfDocs.getMostRecentBatchNumber();
try
{
foreach (PDFDocument doc in parsePDF.listOfDocs)
{
string PDFFileLocation = "C:\\PDFTemp\\ParsedPDF\\" + doc.ID + ".pdf";
PdfExtractorUtility extractPDF = new PdfExtractorUtility();
Directory.SetCurrentDirectory(TempDirectory);
extractPDF.ExtractPages(e.Name, PDFFileLocation, doc.Pages);
LogRow logRow = new LogRow();
logRow.BPNumber = doc.BPNum;
logRow.DocumentNumber = doc.ID;
EDDDocument document = new EDDDocument(doc.ID,fileType,X3Folder);
DirectoryStore networkStore = new DirectoryStore(doc.Month, doc.Day, doc.Year);
networkStore.createDirectory();
//checks if error was thrown when attempting to retrieve email from database
if (document.getEmails())
{
logRow.PrintEmail = "E";
}
else
{
FileInfo file2 = new FileInfo(PDFFileLocation);
//file2.CopyTo(printer + file2.Name);
logRow.PrintEmail = "P";
file2.CopyTo(networkStore.location + file2.Name, true);
}
FileInfo file = new FileInfo(PDFFileLocation);
file.CopyTo(networkStore.location + file.Name, true);
logRow.EmailAddress = document.EmailAdresses;
logRow.Location = networkStore.location + file.Name;
log.Add(logRow);
Guid uniqueID = System.Guid.NewGuid();
PendingTransaction trans = new PendingTransaction(uniqueID, doc.ID, doc.BPNum, document.EmailAdresses, batchNum, false, logRow.PrintEmail, networkStore.location + file.Name);
}
}
catch (Exception f)
{
LogEvent(f.Message);
}
finally
{
if (Directory.Exists(TempDirectory))
{
clearFolder(TempDirectory);
}
if (Directory.Exists(ParseDir))
{
clearFolder(ParseDir);
}
}
}
if (log.Count > 0) { sendDiagnostic(log, batchNum); }
}
where is your FileSystemEventHandler?
Have you looked in the online help about the FileWatcher class
https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
There is an example there of how to use it
https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-2
There is an example there of how to use it
ASKER
Line 39 in my first code post is where I set the FileSystemEventHandler to fire the Onchanged in my 2nd code snippet.
Yes, I did review the MSDN information but I it doesn't explain how to setup the FileSystemWatcher as a service. Like I explained in my original post, my service starts and the Created event does fire my code once when it detects the first file saved to the temp directory. However, any subsequent file, nothing happens. It doesn't seem to be catching any errors either.
Thanks for everyone's comments thus far.
@CreativeTechie
Yes, I did review the MSDN information but I it doesn't explain how to setup the FileSystemWatcher as a service. Like I explained in my original post, my service starts and the Created event does fire my code once when it detects the first file saved to the temp directory. However, any subsequent file, nothing happens. It doesn't seem to be catching any errors either.
Thanks for everyone's comments thus far.
@CreativeTechie
instead of doing all that process in you OnChanged event handler, have you tried just to call something really simple like your LogEvent? Your file might not be ready to be processed when that event is triggered.
Also, have a look at http://emoreau.com/Entries/Articles/2005/04/The-FileSystemWatcher-component.aspx
Also, have a look at http://emoreau.com/Entries/Articles/2005/04/The-FileSystemWatcher-component.aspx
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Great solution! I spent a couple hours looking at this and couldn't figure it out. I am now writing exceptions to a log file and that seems to have done the trick.