User code with FileSystemWatcher hangs?

Experiences, small talk, and other automation gossip.
valerakopay
Posts: 2
Joined: Fri Jun 22, 2018 11:54 am

User code with FileSystemWatcher hangs?

Post by valerakopay » Fri Jun 22, 2018 12:05 pm

Hi everyone!

Scenario: after Ranorex interaction with some desktop apps I need to find new created files and folder and copy them to another location.
I'm not c# developer, so I just copied some code and it woks fine at visual studio.
Here's code:

Code: Select all

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Drawing;
using System.Threading;
using System.IO;

namespace ConsoleApp1
{
    class Program
    {
        private static string sourcePath;
        private static Boolean stopFlag = false;     
        static void Main(string[] args)
        {
            Watch();
        }

          private static void Watch(string tempFolderPath)
        {
            sourcePath = tempFolderPath;
            FileSystemWatcher watcher = new FileSystemWatcher();
            watcher.IncludeSubdirectories = true;
            watcher.Path = tempFolderPath;
            watcher.NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName;
            watcher.Filter = "*.exe";
            watcher.Created += new FileSystemEventHandler(OnChanged);
            watcher.Created += FileSystemWatcher_Created;
            watcher.EnableRaisingEvents = true;
            while (!stopFlag);
        }
        // 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 FileSystemWatcher_Created(object sender, FileSystemEventArgs e)
        {
            string newFileFullPath = e.FullPath;
            string fName = Path.GetFileName(newFileFullPath);
            try
            {
                File.Copy(newFileFullPath, Path.Combine("f:\\temp\\", fName));
            }
            // Catch exception if the file was already copied.
            catch (IOException copyError)
            {
                Console.WriteLine(copyError.Message);
            }
            Console.WriteLine("new file is found and copied, stopping program");
            stopFlag = true;
        }
        
        public void AdwareDetection(string tempFolderPath)
        {
            Watch(tempFolderPath);
        }
    }
}
My recording is:
1. Run App
2-8 mouse clicks
9. User code (posted above)
10-n mouse clicks.

Problem: program seems running cycled at while (!stopFlag); - I logged every line before and after - it stays here. :cry:
I suppose that this code at visual studio and at ranorex studio is run in some different ways, and maybe another way for file creation awaiting should be used.
Any suggestions? :oops:

valerakopay
Posts: 2
Joined: Fri Jun 22, 2018 11:54 am

Re: User code with FileSystemWatcher hangs?

Post by valerakopay » Mon Jun 25, 2018 1:46 pm

User Code started to work as it should when I started Watch() function in another Thread:

Code: Select all

newThread = new Thread(new ThreadStart(Watch));
newThread.Start();
newThread.Join();
But now user code works in eternal cycle "while(true)".
Is it possible to stop it from outside?
The best way to stop it would be trigger "wait for element" from next step in recording.

McTurtle
Posts: 191
Joined: Thu Feb 23, 2017 10:37 am
Location: Benedikt, Slovenia

Re: User code with FileSystemWatcher hangs?

Post by McTurtle » Wed Jun 27, 2018 1:20 pm

Hi valerakopay,

The code that you are using will start to watch for any changes in the folder that you pass into the method AdwareDetection(). If I can read the code correctly, then this is how it is intended to be used, not by calling Watch() directly.

When a change happens, then the code will copy the newly created exe file into the folder "f:\\temp\\". So, if your "2-8 mouse clicks" trigger the creation of the exe file (if you want other file types, then you have to expand the filter in the code method Watch()), then this will most likely happen already before your code in the 2nd thread starts running (watching the folder).

Since you have also joined the thread right after starting it, then the code will wait for any new changes. These won't happen because they are most likely already completed and even if they were not, you have just blocked the main thread by calling join() so it can't do anything until the AdwareDetection() has exited.

If you for some urgent reason must use multi-threading, then I would suggest that you start the 2nd thread before the actions that create the new files/folders and then use join() after the files have been created and copied.

However, I do think that there is no need to use multi-threading in this case at all. Since this is very complicated and both of us seem to have very little experience with it, I would strongly advice that you don't use multi-threading at all. Do you have a very good reason for using this approach? Can you explain?

Regards,
McTurtle