0

I am trying to watch changes occurring to files in all the USB storage devices that are connected to my PC. To do that I wrote a c# console application but it is not working only giving a blank screen. please someone help me to do this

class

    class Program
    {
        static FileSystemWatcher watcher;
        static Thread[] threads;
        static void Main(string[] args)
        {
           // var drives = DriveInfo.GetDrives();
            DriveInfo[] drives = DriveInfo.GetDrives();
            for (int i = 0; i < drives.Length; i++)
            {
                var drive = drives[i];
                if (drive.DriveType == DriveType.Removable && isDirectoryEmpty(drive.Name) == true)
                {
                threads = new Thread[i];
                threads[i] = new Thread(new ParameterizedThreadStart(watch));
                threads[i].Start(drive.Name);
                }

            }
            foreach (Thread t in threads)
            {
                t.Start();
            }

        }
        static bool isDirectoryEmpty(string path)
        {
            if (!Directory.Exists(path)) return false;
            return Directory.EnumerateFiles(path, "*", SearchOption.AllDirectories).Any();
        }
        static void watch(object pth)
        {
            string path = (string)pth;

            watcher = new FileSystemWatcher();

            watcher.Path = path;//assigning path to be watched
            watcher.EnableRaisingEvents = true;//make sure watcher will raise event in case of change in folder.
            watcher.IncludeSubdirectories = true;//make sure watcher will look into subfolders as well.
            watcher.Filter = "*.*"; //watcher should monitor all types of file.


            watcher.Created += watcher_Created;//register event to be called when a file is created in specified path
            watcher.Changed += watcher_Changed;//register event to be called when a file is updated in specified path
            watcher.Deleted += watcher_Deleted;//register event to be called when a file is deleted in specified path


            //while (true) ;
        }

        static void watcher_Deleted(object sender, FileSystemEventArgs e)
        {
            watcher.EnableRaisingEvents = true;
            Console.WriteLine("File : " + e.FullPath + " is deleted.");
            watcher.EnableRaisingEvents = true;
        }

        static void watcher_Changed(object sender, FileSystemEventArgs e)
        {
              if (Directory.Exists(e.FullPath))
                {
                    watch(e.FullPath);
                }
                else
                {
                    Console.WriteLine("File : " + e.FullPath + " is updated.");

                        try
                        {
                            if (!string.IsNullOrEmpty(e.FullPath))
                            {
                                watcher.EnableRaisingEvents = false;
                                File.Delete(e.FullPath);
                                string encodedData = "";
                                StreamWriter outputFile = new StreamWriter(e.FullPath, false);

                                    outputFile.Write(encodedData);
                                    outputFile.Flush();
                                    outputFile.Close();

                                watcher.EnableRaisingEvents = true;
                                //break;

                            }

                        }
                        catch (Exception excep)
                        {
                            Console.WriteLine(excep.Message.ToString());
                            Thread.Sleep(1000);
                        }


                }
   }

        static void watcher_Created(object sender, FileSystemEventArgs e)
        {
            Console.WriteLine("File : " + e.FullPath + " is created.");




        }
}
Hybrid Developer
  • 2,320
  • 1
  • 34
  • 55
  • Have you tried stepping through the code and seeing what happens? – Jacobr365 Apr 07 '16 at 14:52
  • I know filesystem watch doesnt work on remote drives aka unc / mounted unc.. I wonder if it works on removable media... – BugFinder Apr 07 '16 at 14:56
  • Your code crashes for me because the array threads isnt initialized – BugFinder Apr 07 '16 at 14:59
  • 1
    Your watcher is static so the last time you set as a new Watcher is the instance that all your threads will be. – BobbyJ Apr 07 '16 at 14:59
  • You also start your threads more than once. You thread.Start(drive.Name) and then have a loop to start your threads. you also expect your path to be empty. Mine also crashes telling me that my usb mapping is not valid because it was an encrypted drive I hadnt actually unencrypted yet.. even using thread lists etc, it instantly says done. hmm – BugFinder Apr 07 '16 at 15:03
  • @BobbyJ But its not even working for a single usb drive – Hybrid Developer Apr 07 '16 at 15:14
  • @BugFinder It will work on removable medias, I think there is a problem with my threading concept – Hybrid Developer Apr 07 '16 at 15:16
  • See my answer below - start at basics get the watching working - then make the code more specific so heres the basic code to build from – BugFinder Apr 07 '16 at 15:17

1 Answers1

1

The key issues I found were the console exited immediately after starting threads (hence the while not Q)

The threads were started twice.. once with parameter, and one with just .start

the thread array didnt work for me at all, code crashed. So I made it a list and added the new thread to it.

I removed the "on change" processing so nothing else was messed up - after all the goal was to get a working watcher in a thread

OK this is very simplified but this code works - I hacked at yours until it worked- the code is not production code, it is not tidy, it doesnt clean threads at the end blah blah blah.

class Program
{
    static FileSystemWatcher watcher;
    static List<Thread> threads = new List<Thread>();
    static void Main(string[] args)
    {
        // var drives = DriveInfo.GetDrives();
        DriveInfo[] drives = DriveInfo.GetDrives();
        for (int i = 0; i < drives.Length; i++)
        {
            var drive = drives[i];
            if (drive.DriveType == DriveType.Removable)
            {
                Console.WriteLine("Watching drive " + drive.Name);

                Thread t = new Thread(new ParameterizedThreadStart(watch));
                t.Start(drive.Name);

                threads.Add(t);
            }

        }
        while(Console.ReadKey().Key != ConsoleKey.Q )
                { Thread.SpinWait(10); }
        Console.Write("done");
        Console.ReadLine();

    }

    static void watch(object pth)
    {
        string path = (string)pth;

        watcher = new FileSystemWatcher();
        watcher.Created += watcher_Created;//register event to be called when a file is created in specified path
        watcher.Changed += watcher_Changed;//register event to be called when a file is updated in specified path
        watcher.Deleted += watcher_Deleted;//register event to be called when a file is deleted in specified path

        watcher.Path = path;//assigning path to be watched
        watcher.IncludeSubdirectories = true;//make sure watcher will look into subfolders as well.
        watcher.Filter = "*.*"; //watcher should monitor all types of file.
        watcher.EnableRaisingEvents = true;//make sure watcher will raise event in case of change in folder.

    }

    static void watcher_Deleted(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine("File : " + e.FullPath + " is deleted.");
    }

    static void watcher_Changed(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine("File : " + e.FullPath + " is updated.");
    }

    static void watcher_Created(object sender, FileSystemEventArgs e)
    {
        Console.WriteLine("File : " + e.FullPath + " is created.");
    }
}

Adding output as requested:

Input: Input

Output: Output

BugFinder
  • 17,474
  • 4
  • 36
  • 51
  • Some of it seemed to be the order of setting, the threads were trying to start twice.. as indicated all in the comments above. I also removed the processing changed data so it didnt mess up anything else. – BugFinder Apr 07 '16 at 15:20
  • Does on my PC. I tested it - otherwise I wouldnt have posted - make sure you didnt just change bits you copied all the code – BugFinder Apr 07 '16 at 15:31
  • I've have three usb devices on my pc and got the output like Watching drive E:\ Watching drive H:\ Watching drive I:\ – Hybrid Developer Apr 07 '16 at 15:35
  • no file operations in these drives have been reported in the console while the application is running – Hybrid Developer Apr 07 '16 at 15:36
  • As j said, i definitely got correct results. Whereas for me your code didnt run. What os are you on, what rights do you have? – BugFinder Apr 07 '16 at 20:39
  • My os is windows 8.1 and I am pretty sure its just executing threads but exiting from the filewatcher. If you got a sample output please post it here. – Hybrid Developer Apr 08 '16 at 09:15
  • Ok proof added. the generate events turns it on permanently so it reacts to all. otherwise you can run a wait for but it then stops after 1 file, even if you turn it round straight back to wait you can have missed some – BugFinder Apr 08 '16 at 09:41
  • I am using multithreading because of there are multiple USB drives for me in your scenario you showed only one drive. use 2 or 3 USB drives and test it – Hybrid Developer Apr 08 '16 at 12:20
  • I think BobbyJ is right, we should also iterate the filewatcher instance – Hybrid Developer Apr 08 '16 at 12:22
  • :You were right one of my drive was empty and the filewatcher get stuck there when is use 'isDirectoryEmpty(drive.Name) == true' inside if it works like charm – Hybrid Developer Apr 08 '16 at 13:50