Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

FileSystemWatcher.SynchronizingObject without a form

I have an windows form application written in C# in which I use a FileSystemWatcher to monitor a folder for new files and then perform some processing on them. My application is designed to run in the system tray and therefore does not instantiate any forms at startup. The problem is that the Created event is firing on a separate thread and when I try to create an instance of a form in the Created event I get an ThreadStateException that states I need to be running in SingleThreadApartment. I think I need to set the FileSystemWatcher.SynchronizingObject property but don't know what to use since there is no main form in my application.

like image 589
AdmSteck Avatar asked Feb 17 '10 21:02

AdmSteck


People also ask

Which of the following are types of changes that can be detected by the FileSystemWatcher?

The FileSystemWatcher lets you detect several types of changes in a directory or file, like the 'LastWrite' date and time, changes in the size of files or directories etc. It also helps you detect if a file or directory is deleted, renamed or created.

What is FileSystemWatcher?

Use FileSystemWatcher to watch for changes in a specified directory. You can watch for changes in files and subdirectories of the specified directory. You can create a component to watch files on a local computer, a network drive, or a remote computer.

What is the parameter that has to be used when a file is renamed after setting a FileSystemWatcher on the file?

If we want to notify the administrator, that a file has been changed, we would require the name of the file to which the change has been made. To get the name of the file we use the event handler argument FileSystemEventArgs.


2 Answers

You will have to call Application.Run() in your Main() method to get the Windows Forms synchronziation machinery in place so that FileSystemWatcher can properly marshal the call to the main thread. The problem you'll have then is that the main form will become visible. Fix that by pasting this code into the class:

    protected override void SetVisibleCore(bool value) {
        if (!this.IsHandleCreated) {
            this.CreateHandle();
            value = false;
        }
        base.SetVisibleCore(value);
    }

There are no restrictions on what your form looks like if you do this.

like image 63
Hans Passant Avatar answered Nov 02 '22 22:11

Hans Passant


You don’t need to pass any forms to Application.Run at all. Then you can save having to mess around with form visibility. Just do this:

var InvokerForm = new Form();
var dummy = InvokerForm.Handle; // force handle creation
Application.Run();

Just one gotcha there - the form handle creation needs to be forced by accessing it once.

like image 21
Roman Starkov Avatar answered Nov 03 '22 00:11

Roman Starkov