FileSystemWatcher - Cannot do this without API? - vb.net

I want to check out if several folders are receieving new files and then handle that. This works fine, I have declared the FileSystemWatcher and set the EventHandler.
Now, everything works fine and if I create a new file there, it notices it.
Then, I noticed that when I paste a file, it does not notice it. I have already searched on Google and I read that it is not possible with the built-in FileSystemWatcher so far.
So I thought about API to manage this, but I have actually no idea how to deal with that or where to start. This program is one for a job, so I really need that.
I appreciate any help, links or something else to deal with that.
Thanks! if something is not clear, avoid a Downvote and ask me ;)

The following works completed as expected (.net v4.5). A paste into the directory fires the Change event.
Public Class Form1
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim fw As New FileSystemWatcher
fw.Path = "c:\Temp"
fw.Filter = "*.*"
fw.IncludeSubdirectories = False
AddHandler fw.Created, New FileSystemEventHandler(AddressOf FileWatcherFileChange)
AddHandler fw.Deleted, New FileSystemEventHandler(AddressOf FileWatcherFileDeleted)
AddHandler fw.Renamed, New RenamedEventHandler(AddressOf FileWatcherFileRenamed)
AddHandler fw.Error, New ErrorEventHandler(AddressOf FileWatcherError)
fw.EnableRaisingEvents = True
End Sub
Private Sub FileWatcherFileChange(ByVal source As Object, ByVal e As FileSystemEventArgs)
MsgBox("Change")
End Sub
Private Sub FileWatcherFileDeleted(ByVal source As Object, ByVal e As FileSystemEventArgs)
MsgBox("Deleted")
End Sub
Private Sub FileWatcherFileRenamed(ByVal source As Object, ByVal e As FileSystemEventArgs)
MsgBox("Renamed")
End Sub
Private Sub FileWatcherError(ByVal source As Object, ByVal e As System.IO.ErrorEventArgs)
MsgBox("Error")
End Sub
End Class

There were so many comments, I want to ensure you read this so I post as an answer. Please read this answer from me in another thread in full, including what is written on CodeProject. If what you are delivering is important work code you should really take the time to read it all.
This FileSystemWatcher class features many surprises. It is a leaky abstraction - it doesn't work in any way like it should. It might work for a while, but it always fails when conditions change.
If I were you I would ditch the FileSystemWatcher class entirely and work with time and date based scans for new files. There may be other classes and pre-made components that can help you with this.
UPDATE: New information: https://stackoverflow.com/a/23704476/129130

Related

Download, get the filename and execute the file

I am posting here to ask you for help, thank you first of all for reading my message and being able to help me. :)
So here's the problem, I have a little program that I'm creating, in this one, I integrated a button that normally allows to download a tool to run it.
However the link of the file does not point directly in .exe it is a link like this one :
mydomain.com/file/file48.php
The problem is that I manage to get the file, but this one is named file48.php and gets the extension of a php file, what I would like is to get the original name of the downloaded .exe file in order to be able to execute it within my application.
Here is the current code I'm using :
Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
Dim client As New WebClient
AddHandler client.DownloadFileCompleted, AddressOf client_DownloadFileCompleted
client.DownloadFileAsync(New Uri("https ://mydomain.com/files/index.php"), fileName, filename)
End Sub
Private Sub client_DownloadFileCompleted(sender As Object, e As AsyncCompletedEventArgs)
Dim client = DirectCast(sender, WebClient)
client.Dispose()
Dim filename As String = CType(e.UserState, String)
End Sub
Thanks a lot for your help, I've been searching for hours without much success...

Catching unhandled exceptions decision

I decided to turn on the strict option on one of my applications. And for the life of me I couldn't figure out how to make a small bit of code compile. In a module I had this bit of code
Sub Main()
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException
End Sub
Private Sub CurrentDomain_UnhandledException(sender As Object, e As UnhandledExceptionEventArgs)
e.ExitApplication = False
End Sub
after looking around and seeing another post about putting it in the ApplicationEvents I got it to work by handling said event. So out curiosity I decided to move the AddHandler and into the same class and then it became clear that its the same class name but different namespaces:
Partial Friend Class MyApplication
Private Sub MyApplication_UnhandledException(sender As Object, e As UnhandledExceptionEventArgs) Handles Me.UnhandledException
e.ExitApplication = False
AddHandler AppDomain.CurrentDomain.UnhandledException, AddressOf CurrentDomain_UnhandledException
End Sub
Private Sub CurrentDomain_UnhandledException(sender As Object, e As System.UnhandledExceptionEventArgs)
e.ExitApplication = False
End Sub
End Class
Here is a link to both:
Microsoft.VisualBasic.ApplicationServices.UnhandledExceptionEventArgs
System.UnhandledExceptionEventArgs
So my question is, which one should I use? I'm wanting to prevent the app from shutting down... but both options seem like what I want.
The System.UnhandledException doesn't have an ExitApplication member (see the docs you linked), so cannot be used to stop the application exiting - once this is called the application will always terminate. Generally the Microsoft.VisualBasic namespace are helpers for VB that more-or-less duplicate functionality available elsewhere. The closest equivalent to the VisualBasic handler that you mention is instead the Application.ThreadException one. This and the AppDomain.CurrentDomain.UnhandledException are both described quite well in the MS docs.
To prevent the app from shutting either the VisualBasic one or the ThreadException one can be used. I've used the Microsoft.VisualBasic one in the past to achieve something similar to what you are doing.

using GoogleEarth plugin from VB.NET through FC.GEPluginCtrls

I'm really looking for a simple way to build VB.NET apps that use the GEplugin. So I have found this project that seems to do the dirty job I need: http://code.google.com/p/winforms-geplugin-control-library/
Well, all the code posted there around works on C#, but I need to have it on VB.NET. So I have tried this:
created a new 32-bit solution from VB.NET 2010 Express (I simply added
<PlatformTarget>x86</PlatformTarget >
inside the .vbproj file)
added a reference to FC.GEPluginCtrls.dll
inserted a GeWebBrowser control on the form
at the top of the code, added
Imports FC.GEPluginCtrls
then, in the form Load event, put this code:
InitializeComponent()
GeWebBrowser1.LoadEmbeddedPlugin()
Do
Loop Until GeWebBrowser1.PluginIsReady = False
GeWebBrowser1.CreateInstance(ImageryBase.Earth)
that, I think, would be equivalent to
http://code.google.com/p/winforms-geplugin-control-library/wiki/CreateInstance
So, the project compiles and doesn't get errors, but the GeWebBrowser control remains empty.
I actually wrote the library you are using. You are not listening for the PluginReady event. http://code.google.com/p/winforms-geplugin-control-library/wiki/PluginReady
To use it with VB simply convert the basic examples to VB -
http://code.google.com/p/winforms-geplugin-control-library/wiki/ExampleForm
Also, a loop polling PluginIsReady is totally unnecessary as the PluginReady event is asynchronous.
To show the earth all you would need is the following.
Private Sub Form1_Load( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
GeWebBrowser1.LoadEmbeddedPlugin()
End Sub
To use the plugin when it has initialzesd use the PluginReady event. Something like.
Option Strict Off
Public Class Form1
Private Dim _ge as Object = Nothing
Private Sub GeWebBrowser1_PluginReady( ByVal sender As System.Object, ByVal e As FC.GEPluginCtrls.GEEventArgs) Handles GeWebBrowser1.PluginReady
_ge = e.ApiObject ' reference to the Google Earth Plugin object
MessageBox.Show(_ge.getApiVersion()) ' _ge is the plugin -use it just as in the javascript api...
End Sub
Private Sub Form1_Load( ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
GeWebBrowser1.LoadEmbeddedPlugin() ' load the plugin
End Sub
End Class

Pressing a button in visual basic

I am new to Visual Basic.NET and I am just playing around with it. I have a book that tells me how to read from a file but not how to write to the file with a button click. All I have is a button and a textbox named fullNameBox. When I click the button it gives me an unhandled exception error. Here is my code:
Public Class Form1
Sub outputFile()
Dim oWrite As System.IO.StreamWriter
oWrite = System.IO.File.CreateText("C:\sample.txt")
oWrite.WriteLine(fullNameBox.Text)
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
outputFile()
End Sub
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
End Sub
End Class
Have you tried stepping through your application to see where the error is? With a quick glance, it looks like you might need to use System.IO.File on the fourth line (oWrite = IO.File...) instead of just IO, but I haven't tried to run it.
Imports System.IO
Public Class Form1
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
SaveFileDialog1.FileName = ""
SaveFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"
SaveFileDialog1.ShowDialog()
If SaveFileDialog1.FileName.Trim.Length <> 0 Then
Dim fs As New FileStream(SaveFileDialog1.FileName.Trim, FileMode.Create)
Dim sr As New StreamWriter(fs)
sr.Write(TextBox1.Text)
fs.Flush()
sr.Close()
fs.Close()
End If
End Sub
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
OpenFileDialog1.FileName = ""
OpenFileDialog1.Filter = "txt files (*.txt)|*.txt|All files (*.*)|*.*"
OpenFileDialog1.ShowDialog()
If OpenFileDialog1.FileName.Trim.Length <> 0 Then
Dim fs As New FileStream(OpenFileDialog1.FileName.Trim, FileMode.Open)
Dim sw As New StreamReader(fs)
TextBox1.Text = sw.ReadToEnd
fs.Flush()
sw.Close()
fs.Close()
End If
End Sub
End Class
this is a complete functional program if you want, you just need to drag drop a textbox, openfiledialog, and a savefiledialog.
feel free to play around with the code.
enjoy
by the way, the problem in your code is that you "must" close filestream when your done using it, doing so will release any resource such as sockets and file handles.
The .net framework is a very powerful framework. In the same way (however) it has easy and convenient methods for simple tasks. Most individuals tend to complicate things in order to display knowledge. But less code = less processing = faster and more efficient application (sometimes) so the large above method may not be suitable. Along with that, the above mentioned method would be better off written as a sub or if returning something then a function.
My.Computer.FileSystem.WriteAllText("File As String", "TextAsString", Append as Boolean)
A general Example would be
My.Computer.FileSystem.WriteAllText("C:\text.text", "this is what I would like to add", False)
this is what I would like to add
can be changed to the current text of a field as well.
so a more specific example would be
My.Computer.FileSystem.WriteAllText("C:\text.text", fullNameBox.text, True)
If you would like to understand the append part of the code
By setting append = true you are allowing your application to write the text at the end of file, leaving the rest of the text already in the file intact.
By setting append = false you will be removing and replacing all the text in the existing file with the new text
If you don't feel like writing that part of the code (though it is small) you could create a sub to handle it, however that method would be slightly different, just for etiquette. functionality would remain similar. (Using StreamWriter)
Private Sub WriteText()
Dim objWriter As New System.IO.StreamWriter("file.txt", append as boolean)
objWriter.WriteLine(textboxname.Text)
objWriter.Close()
End Sub
The Specific Example would be
Private Sub WriteText()
Dim objWriter As New System.IO.StreamWriter("file.txt", False)
objWriter.WriteLine(fullnamebox.Text)
objWriter.Close()
End Sub
then under the button_click event call:
writetext()
You can take this a step further as well. If you would like to create a more advabced Sub to handle any textbox and file.
Lets say you plan on having multiple separate files and multiple fields for each file (though there is a MUCH cleaner more elegant method) you could create a function. {i'll explain the concept behind the function as thoroughly as possible for this example}
below is a more advanced sub demonstration for your above request
Private Sub WriteText(Filename As String, app As Boolean, text As String)
Dim objWriter As New System.IO.StreamWriter(Filename, app)
objWriter.WriteLine(text)
objWriter.Close()
End Sub
What this does is allows us to (on the same form - if you need it global we can discuss that another time, it's not much more complex at all) call the function and input the information as needed.
Sub Use -> General Sample
WriteText(Filename As String, app As Boolean)
Sub Use -> Specific Sample
WriteText("C:\text.txt, False, fullnamebox.text)
But the best part about this method is you can change that to be anything as you need it.
Let's say you have Two Buttons* and **Two Boxes you can have the button_event for the first button trigger the above code and the second button trigger a different code.
Example
WriteText("C:\text2.txt, False, halfnamebox.text)
The best part about creating your own functions and subs are Control I won't get into it, because it will be off topic, but you could check to be sure the textbox has text first before writing the file. This will protect the files integrity.
Hope this helps!
Richard Sites.

VB.NET DownloadDataAsync:

I am having the worst trouble getting around a bug, and am hoping that I can get some advice on this site. In short, I am trying to make an asynchronous web service call from my VB.NET application. But my "client_DownloadDataCompleted" callback is NEVER being called when the download is complete.
Here is my complete code:
Public Sub BeginAsyncDownload(ByVal Url As String)
Dim waiter As System.Threading.AutoResetEvent = New System.Threading.AutoResetEvent(False)
Dim client As WebClient = New WebClient()
'client_DownloadDataCompleted method gets called when the download completes.
AddHandler client.DownloadDataCompleted, AddressOf client_DownloadDataCompleted
Dim uri As Uri = New Uri(Url)
Downloading = True 'Class variable defined elsewhere
client.DownloadDataAsync(uri, waiter)
End Sub
Private Sub client_DownloadDataCompleted(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs)
MessageBox.Show("Download Completed")
Downloading = False
Debug.Print("Downloaded")
End Sub
Again, the client_DownloadDataCompleted method is never being called. I have also tried using the method:
Private Sub client_DownloadDataCompleted(ByVal sender As Object, ByVal e As DownloadDataCompletedEventArgs)
With no luck. What I really need is that "Downloading" variable to be switched off when the download is complete.
Thanks in advance!
Brett
The client (Webclient) should be declared outside the BeginAsyncDownload subroutine, so it has a form/class level visibility. Please refer to the following code:
Public Class Form1
Dim client as New WebClient()
Private Sub BeginAsyncDownload(ByVal Url As String)
AddHandler client.DownloadDataCompleted, AddressOf client_DownloadDataCompleted
Dim uri As Uri = New Uri(Url)
Downloading = True 'Class variable defined elsewhere
client.DownloadDataAsync(uri, waiter)
End Sub
Private Sub client_DownloadStringCompleted(ByVal sender As Object, ByVal e As System.Net.DownloadStringCompletedEventArgs)
MessageBox.Show("Download Completed")
Downloading = False
Debug.Print("Downloaded")
End Sub
This is a tough one. I spent a little time on this and wasn't able to figure out why it wasn't getting called, sorry.
If you aren't able to get this to work, I have some code on CodePlex that includes a WebHelper class that might help you. I tried to make it as easy to use as WebClient but with all the power of HttpWebRequest.
The project is called BizArk. I wrote it just as a repository of code for myself. Feel free to just use the bits you want, I don't have any particular interest in how the code is used (as long as it's not used for evil :).
In what context are you invoking the webclient? WebClient will pick up your SynchronizationContext.Current and post its completion callback to it.
If you are using WinForms and your UI thread is blocked it will never be able to process your callback.