File monitor/copy code doesn't catch everything

T

TwistedPair

All,
This is sort of a continuation of a previous post of mine. The code below
basically reads a registry key to get a path to a folder and it watches for
files created in that folder (only created). It also reads another registry
key for another path which is a destination path. When a file shows up, it
copies it off.

It actually works well . . . For small duty stuff but if for example I were
to copy in multiple small files simulteneously into the source folder, it
only copies the first one it sees. It sorta peeters out after that, and I
don't think it continues on copying.

Also, if I drop a large file -- 500MB or higher -- into the folder, it
starts copying, but if I drop another file in the folder during this time,
it doesn't pick it up. I don't think it even finished copying the large
file.

Just wanted to see if y'all could give me some direction/advice.

TIA,
Pair

Imports System.ServiceProcess

Imports System.Threading

Public Class Service1

Inherits System.ServiceProcess.ServiceBase

Dim DestDirectory As String

Dim WatchDirectory As String

Private Watchservice As New Thread(New
System.Threading.ThreadStart(AddressOf StartMonitor))

#Region " Component Designer generated code "

Public Sub New()

MyBase.New()

' This call is required by the Component Designer.

InitializeComponent()

' Add any initialization after the InitializeComponent() call

End Sub

'UserService overrides dispose to clean up the component list.

Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)

If disposing Then

If Not (components Is Nothing) Then

components.Dispose()

End If

End If

MyBase.Dispose(disposing)

End Sub

' The main entry point for the process

<MTAThread()> _

Shared Sub Main()

Dim ServicesToRun() As System.ServiceProcess.ServiceBase

' More than one NT Service may run within the same process. To add

' another service to this process, change the following line to

' create a second service object. For example,

'

' ServicesToRun = New System.ServiceProcess.ServiceBase () {New Service1,
New MySecondUserService}

'

ServicesToRun = New System.ServiceProcess.ServiceBase() {New Service1}

System.ServiceProcess.ServiceBase.Run(ServicesToRun)

End Sub

'Required by the Component Designer

Private components As System.ComponentModel.IContainer

' NOTE: The following procedure is required by the Component Designer

' It can be modified using the Component Designer.

' Do not modify it using the code editor.

<System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()

components = New System.ComponentModel.Container()

Me.ServiceName = "Service1"

End Sub

#End Region

Protected Overrides Sub OnStart(ByVal args() As String)

' Start the thread.

Watchservice.Start()

End Sub

Protected Overrides Sub OnStop()

' Add code here to perform any tear-down necessary to stop your service.

Watchservice.Abort()

End Sub

Private Sub StartMonitor()

Do

WatchDirectory =
My.Computer.Registry.GetValue("HKEY_LOCAL_MACHINE\Software\CopyMon",
"Source", Nothing)

DestDirectory =
My.Computer.Registry.GetValue("HKEY_LOCAL_MACHINE\Software\CopyMon",
"Destination", Nothing)

Dim watcher As New System.IO.FileSystemWatcher(WatchDirectory)

Dim result

AddHandler watcher.Created, AddressOf logchange

'Dim SourceFileNameObject As IO.WaitForChangedResult

'Dim SourceFileName As String

'SourceFileName = SourceFileNameObject.Name

'MsgBox(SourceFileName)

result = watcher.WaitForChanged(System.IO.WatcherChangeTypes.Created)

Loop

End Sub

Private Sub logchange(ByVal source As Object, ByVal e As
System.IO.FileSystemEventArgs)

Dim SourceFilePath As String

Dim SourceFileName As String

Dim DestPath As String

If e.ChangeType = IO.WatcherChangeTypes.Created Then

SourceFilePath = e.FullPath

SourceFileName = e.Name

'MsgBox(SourceFilePath)

'MsgBox(DestDirectory & "\" & SourceFileName)

DestPath = DestDirectory & "\" & SourceFileName

My.Computer.FileSystem.CopyFile(SourceFilePath, DestPath)

End If

End Sub

End Class
 
C

Chris Dunaway

All,
This is sort of a continuation of a previous post of mine. The code below
basically reads a registry key to get a path to a folder and it watches for
files created in that folder (only created). It also reads another registry
key for another path which is a destination path. When a file shows up, it
copies it off.

It actually works well . . . For small duty stuff but if for example I were
to copy in multiple small files simulteneously into the source folder, it
only copies the first one it sees. It sorta peeters out after that, and I
don't think it continues on copying.

What you see as 'simultaneous' copying of several files, to the
computer is probably not simultaneous at all. It probably sees the
creation of the first file and then kicks off it's processing, not
getting an event for the other files. One possible way of getting
around this is when you see the create event, get a list of ALL files
that match your criteria and then copy them all.
Also, if I drop a large file -- 500MB or higher -- into the folder, it
starts copying, but if I drop another file in the folder during this time,
it doesn't pick it up. I don't think it even finished copying the large
file.

Same as above, once the 500Mb file appears, the file system watcher
fires the created event and your code launches into the long process
of copying the file. Other files copied after that, don't get
events.

One method would be to simply have your FileSystemWatcher add the
filename to a queue or list and then go back to watching for files.
The copying process could be kicked off using a background thread
which continually monitors the queue and if a filename is found there,
copies it. So you would have two separate processes. One which uses
the FileSystemWatcher to monitor for files and insert their names into
a queue and another to watch the queue and do the actual copying.

Hopefully this will give you some ideas.

Chris
 
T

TwistedPair

Yes it does! I was wondering if that was indeed the best way to handle it,
and now I suppose I have confirmation. Now all I have to do is figure out
how. Thank you for your pointers, and any others would be greatly
appreciated as well!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top