Running windows task based on folder change event

0

I have been trying to get a way of running a windows task based on event. The event is a file being changed on a folder. This file is being changed by another process that I do not have control over. However when that file changes, I need a certain windows task to be triggered. Preferably the solution must be in C# because the policy in our company does not allow the running of PowerShell scripts.

Your help will be highly appreciated.

Thanks Bheki

Bheki

Posted 2019-02-01T08:51:24.953

Reputation: 1

ReadDirectoryChangesW function? – Akina – 2019-02-01T10:04:19.210

Hi Akina. Thanks. I have been searching and by combining information from multiple posts and experience, I have found a solution that works. I will post the solution shortly. – Bheki – 2019-02-09T12:09:12.493

Answers

0

I have been battling with an answer to this question and after a lot of researching, I combined the info with my experience and found the answer to be as follows:

 //Purpose: Monitor changes to a folder and write to event log when a change 
 // happens. 
 //Last Mod date: 09/01/2019
 //Author: Bheki
 //Notes: The target folder is given in the parameter file. The first time the application runs must be run as an administrator.

 using System;
 using System.IO;
 using System.Security.Permissions;
 using System.Diagnostics;
 using System.Threading;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
 using System.Collections.Generic;
 using System.Windows;


 public class Watcher
 {

 public static void Main()
 {


    Run();


}

[PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
public static void Run()
{




    // Create a new FileSystemWatcher and set its properties.
    FileSystemWatcher watcher = new FileSystemWatcher();
    watcher.Path = Watcher.GetTargetFolder().Item1;
    /* 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 = Watcher.GetTargetFolder().Item2;

    // 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;

    // Wait for the user to quit the program.
    Console.WriteLine("Press \'q\' to quit the sample.");
    while (Console.Read() != 'q') ;
}

public static Tuple<string,string> GetTargetFolder()
{
    string currentRecordOpenFile;
    char ColumnDelimter = ","[0];

    string TargetFolder = "";
    string FixSelected = "";
    string FileExtension = "";
    string SecondHeader = "";

    TargetFolder = System.IO.Directory.GetCurrentDirectory().Replace("\\", "/");



    string ParameterFile = TargetFolder + "/ParameterFile.txt";
    using (StreamReader objReader = new StreamReader(ParameterFile.Replace("\\", "/")))
    {
        while (!objReader.EndOfStream)
        {
            currentRecordOpenFile = objReader.ReadLine(); //this reads a whole line of input from the file
            string[] LineOfFile = currentRecordOpenFile.Split(ColumnDelimter);
            if (LineOfFile[0] == "Pathtofiles")
            {
                //we can skip the heading
                continue;
            }
            else
            {

                    TargetFolder = LineOfFile[0].Replace("\\", "/") + "/";    //this can be changed depending on how the output looks
                    FixSelected = LineOfFile[1];
                    FileExtension = LineOfFile[2];
                    SecondHeader = LineOfFile[3];


            }

        }


        return Tuple.Create(TargetFolder, FileExtension);
    }//End of stream for reading the parameter file   
}

// 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);

    string vLog = "Application";
    string vSource = "BCMPR";

    if (!EventLog.SourceExists(vSource))
    {
        //An event log source should not be created and immediately used.
        //There is a latency time to enable the source, it should be created
        //prior to executing the application that uses the source.
        //Execute this sample a second time to use the new source.
        EventLog.CreateEventSource(vSource, vLog);
        Console.WriteLine("CreatedEventSource");
        Console.WriteLine("Exiting, execute the application a second time to use the source.");
        // The source is created.  Exit the application to allow it to be registered.
        return;
    }

    // Create an EventLog instance and assign its source.



        EventLog myLog = new EventLog();
        myLog.Source = vSource;

        Console.WriteLine("File: " + e.FullPath + " " + e.ChangeType);
        Console.WriteLine("Writting to event log");
        // Write an informational entry to the event log.    
        myLog.WriteEntry("The folder has been changed", EventLogEntryType.Information, 1307);

        System.Environment.Exit(0); 



     }


   }

In the same location as the application after it has been built in C#. Please put the ParameterFile.txt file and it has the following contents:

Pathtofiles,FixSelected,FileExtension,SecondHeader
C:\Data\TEST,ALL,*.txt,TEST

Please note that the Folder(C:\Data\TEST) and file extension(*.txt) can be changed to user requirements.

//Windows event viewer and set up

After this code has been run twice and the changes are made to the folder then our event can be seen in windows event viewer. Please follow instructions in the image: Windows Event Log and Task Setup

Bheki

Posted 2019-02-01T08:51:24.953

Reputation: 1