I copied and modified a Filewatcher program from the web and it works fine but I get this error...
"Cross-thread operation not valid: Control 'lstEvents' accessed from a thread other than the thread it was created on."
I've spent hours researching and trying to fix this but I just dont know enough yet to get it.
I've read its as simple as setting the filesystemwatcher SynchronizingObject property to the listbox but I dont even know how to do that yet.
Could someone please give me some specific instructions on how to correct this error
Thanks
John
Imports
SystemImports
System.IOImports
System.TextImports
System.DiagnosticsImports
System.Data.OleDbImports
System.GlobalizationImports
System.ThreadingImports
System.Windows.FormsImports
Microsoft.Office.CoreImports
excel = Microsoft.Office.Interop.excel'
Public
Class Form1 Inherits System.Windows.Forms.Form Public watchfolder As FileSystemWatcher#
Region " Windows Form Designer generated code " Public Sub New() MyBase.New() 'This call is required by the Windows Form Designer.InitializeComponent()
'Add any initialization after the InitializeComponent() call End Sub 'Form 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) Thencomponents.Dispose()
End If End If MyBase.Dispose(disposing) End Sub 'Required by the Windows Form Designer Private components As System.ComponentModel.IContainer 'NOTE: The following procedure is required by the Windows Form Designer 'It can be modified using the Windows Form Designer. 'Do not modify it using the code editor. Friend WithEvents Label1 As System.Windows.Forms.Label Friend WithEvents txt_watchpath As System.Windows.Forms.TextBox Friend WithEvents Label2 As System.Windows.Forms.Label Friend WithEvents btn_startwatch As System.Windows.Forms.Button Friend WithEvents btn_stop As System.Windows.Forms.Button Friend WithEvents Button1 As System.Windows.Forms.Button Friend WithEvents FolderBrowserDialog1 As System.Windows.Forms.FolderBrowserDialog Friend WithEvents chkIncludeSubdirs As System.Windows.Forms.CheckBox Friend WithEvents Label3 As System.Windows.Forms.Label Friend WithEvents XL_file As System.Windows.Forms.TextBox Friend WithEvents lstEvents As System.Windows.Forms.ListBox Friend WithEvents Label4 As System.Windows.Forms.Label Friend WithEvents FileSystemWatcher1 As System.IO.FileSystemWatcher Friend WithEvents XL_file_copy As System.Windows.Forms.TextBox<System.Diagnostics.DebuggerStepThrough()>
Private Sub InitializeComponent() Me.Label1 = New System.Windows.Forms.Label Me.txt_watchpath = New System.Windows.Forms.TextBox Me.Label2 = New System.Windows.Forms.Label Me.btn_startwatch = New System.Windows.Forms.Button Me.btn_stop = New System.Windows.Forms.Button Me.Button1 = New System.Windows.Forms.Button Me.FolderBrowserDialog1 = New System.Windows.Forms.FolderBrowserDialog Me.chkIncludeSubdirs = New System.Windows.Forms.CheckBox Me.Label3 = New System.Windows.Forms.Label Me.XL_file = New System.Windows.Forms.TextBox Me.lstEvents = New System.Windows.Forms.ListBox Me.Label4 = New System.Windows.Forms.Label Me.XL_file_copy = New System.Windows.Forms.TextBox Me.FileSystemWatcher1 = New System.IO.FileSystemWatcher CType(Me.FileSystemWatcher1, System.ComponentModel.ISupportInitialize).BeginInit() Me.SuspendLayout() ' 'Label1 ' Me.Label1.Location = New System.Drawing.Point(16, 16) Me.Label1.Name = "Label1" Me.Label1.Size = New System.Drawing.Size(88, 16) Me.Label1.TabIndex = 0 Me.Label1.Text = "Folder to watch:" ' 'txt_watchpath ' Me.txt_watchpath.Location = New System.Drawing.Point(104, 16) Me.txt_watchpath.Name = "txt_watchpath" Me.txt_watchpath.Size = New System.Drawing.Size(256, 20) Me.txt_watchpath.TabIndex = 1 Me.txt_watchpath.Text = "d:\RADCO" ' 'Label2 ' Me.Label2.Location = New System.Drawing.Point(16, 128) Me.Label2.Name = "Label2" Me.Label2.Size = New System.Drawing.Size(96, 16) Me.Label2.TabIndex = 3 Me.Label2.Text = "Folder Activity" ' 'btn_startwatch ' Me.btn_startwatch.Location = New System.Drawing.Point(376, 16) Me.btn_startwatch.Name = "btn_startwatch" Me.btn_startwatch.Size = New System.Drawing.Size(104, 24) Me.btn_startwatch.TabIndex = 4 Me.btn_startwatch.Text = "Start Watching" ' 'btn_stop ' Me.btn_stop.Location = New System.Drawing.Point(376, 48) Me.btn_stop.Name = "btn_stop" Me.btn_stop.Size = New System.Drawing.Size(104, 24) Me.btn_stop.TabIndex = 5 Me.btn_stop.Text = "Stop Watching" ' 'Button1 ' Me.Button1.Location = New System.Drawing.Point(104, 40) Me.Button1.Name = "Button1" Me.Button1.Size = New System.Drawing.Size(75, 23) Me.Button1.TabIndex = 7 Me.Button1.Text = "Browse" ' 'chkIncludeSubdirs ' Me.chkIncludeSubdirs.Checked = True Me.chkIncludeSubdirs.CheckState = System.Windows.Forms.CheckState.Checked Me.chkIncludeSubdirs.Location = New System.Drawing.Point(224, 40) Me.chkIncludeSubdirs.Name = "chkIncludeSubdirs" Me.chkIncludeSubdirs.Size = New System.Drawing.Size(136, 24) Me.chkIncludeSubdirs.TabIndex = 8 Me.chkIncludeSubdirs.Text = "Include Subdirectories" ' 'Label3 ' Me.Label3.Location = New System.Drawing.Point(16, 80) Me.Label3.Name = "Label3" Me.Label3.Size = New System.Drawing.Size(176, 16) Me.Label3.TabIndex = 9 Me.Label3.Text = "Master Excel file path and name:" ' 'XL_file ' Me.XL_file.Location = New System.Drawing.Point(184, 80) Me.XL_file.Name = "XL_file" Me.XL_file.Size = New System.Drawing.Size(296, 20) Me.XL_file.TabIndex = 10 Me.XL_file.Text = "d:\watch radco folder\RADCO_log.xls" ' 'lstEvents ' Me.lstEvents.Anchor = System.Windows.Forms.AnchorStyles.None Me.lstEvents.IntegralHeight = False Me.lstEvents.Location = New System.Drawing.Point(16, 142) Me.lstEvents.Name = "lstEvents" Me.lstEvents.ScrollAlwaysVisible = True Me.lstEvents.Size = New System.Drawing.Size(464, 162) Me.lstEvents.TabIndex = 11 ' 'Label4 ' Me.Label4.Location = New System.Drawing.Point(56, 104) Me.Label4.Name = "Label4" Me.Label4.Size = New System.Drawing.Size(120, 16) Me.Label4.TabIndex = 12 Me.Label4.Text = "User copy of Excel file:" ' 'XL_file_copy ' Me.XL_file_copy.Location = New System.Drawing.Point(184, 104) Me.XL_file_copy.Name = "XL_file_copy" Me.XL_file_copy.Size = New System.Drawing.Size(296, 20) Me.XL_file_copy.TabIndex = 13 Me.XL_file_copy.Text = "d:\RADCO\RADCO_log.xls" ' 'FileSystemWatcher1 ' Me.FileSystemWatcher1.EnableRaisingEvents = True Me.FileSystemWatcher1.SynchronizingObject = Me ' 'Form1 ' Me.AutoScaleBaseSize = New System.Drawing.Size(5, 13) Me.ClientSize = New System.Drawing.Size(496, 317) Me.Controls.Add(Me.XL_file_copy) Me.Controls.Add(Me.Label4) Me.Controls.Add(Me.lstEvents) Me.Controls.Add(Me.XL_file) Me.Controls.Add(Me.Label3) Me.Controls.Add(Me.chkIncludeSubdirs) Me.Controls.Add(Me.Button1) Me.Controls.Add(Me.btn_stop) Me.Controls.Add(Me.btn_startwatch) Me.Controls.Add(Me.Label2) Me.Controls.Add(Me.txt_watchpath) Me.Controls.Add(Me.Label1) Me.Name = "Form1" Me.Text = "Folder Watch" CType(Me.FileSystemWatcher1, System.ComponentModel.ISupportInitialize).EndInit() Me.ResumeLayout(False) Me.PerformLayout() End Sub#
End Region ' Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click If FolderBrowserDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Thentxt_watchpath.Text = FolderBrowserDialog1.SelectedPath
End If End Sub ' Private Sub btn_startwatch_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_startwatch.Clickwatchfolder =
New System.IO.FileSystemWatcher 'this is the path we want to monitorwatchfolder.Path = txt_watchpath.Text
' Include subdirectories if box checked If chkIncludeSubdirs.CheckState = CheckState.Checked Thenwatchfolder.IncludeSubdirectories =
True End If If chkIncludeSubdirs.CheckState = CheckState.Unchecked Thenwatchfolder.IncludeSubdirectories =
False End If Dim XLFileCopy As String = XL_file_copy.Text Dim XLFile As String = XL_file.Text If File.Exists(XLFile) Then 'Add a list of Filter we want to specify 'make sure you use OR for each Filter as we need to 'all of thosewatchfolder.NotifyFilter = IO.NotifyFilters.DirectoryName
watchfolder.NotifyFilter = watchfolder.NotifyFilter
Or _IO.NotifyFilters.FileName
watchfolder.NotifyFilter = watchfolder.NotifyFilter
Or _IO.NotifyFilters.Attributes
' Only watch for PDF files.watchfolder.Filter =
"*.pdf" ' add the handler to each event ' AddHandler watchfolder.Changed, AddressOf logchange AddHandler watchfolder.Created, AddressOf logchangeAdd AddHandler watchfolder.Deleted, AddressOf logchangeDel ' add the rename handler as the signature is different AddHandler watchfolder.Renamed, AddressOf logrename 'Set this property to true to start watchingwatchfolder.EnableRaisingEvents =
Truebtn_startwatch.Enabled =
Falsebtn_stop.Enabled =
True ' ' Types of changes that can be watched for: ' Attributes (The attributes of the file or folder) ' CreationTime (The time the file or folder was created) ' DirectoryName (The name of the directory) ' FileName (The name of the file) ' LastAccess (The date the file or folder was last opened) ' LastWrite (The date the file or folder last had anything written to it) ' Security (The security settings of the file or folder) ' Size (The size of the file or folder) ElseMessageBox.Show(
"Master Excel File Does Not Exist!") End If 'End of code for btn_start_click End Sub Private Sub logchangeAdd(ByVal source As Object, ByVal e As _System.IO.FileSystemEventArgs)
If e.ChangeType = IO.WatcherChangeTypes.Created Then Dim strText As String = "File " & e.FullPath & " has been created"AddItem(strText)
Add_Record(source, e)
End If End Sub Private Sub logchangeDel(ByVal source As Object, ByVal e As _System.IO.FileSystemEventArgs)
If e.ChangeType = IO.WatcherChangeTypes.Deleted Then Dim strText As String = "File " & e.FullPath & " has been deleted"AddItem(strText)
Add_Record(source, e)
End If End Sub ' Private Sub logchange(ByVal source As Object, ByVal e As _ ' System.IO.FileSystemEventArgs) ' If e.ChangeType = IO.WatcherChangeTypes.Changed Then ' txt_folderactivity.Text = "File " & e.FullPath & _ ' " has been modified" ' ' Add_Record(source, e) ' End If ' End Sub ' Public Sub logrename(ByVal source As Object, ByVal e As _System.IO.RenamedEventArgs)
Dim strText As String = "File" & e.OldName & " has been renamed to " & e.NameAddItem(strText)
End Sub ' Private Sub AddItem(ByVal strText As String)lstEvents.Items.Add(strText)
End Sub Private Sub btn_stop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_stop.Clickwatchfolder.EnableRaisingEvents =
Falsebtn_startwatch.Enabled =
Truebtn_stop.Enabled =
False End Sub ' ' Private Sub Add_Record(ByVal source As Object, ByVal e As System.IO.FileSystemEventArgs) Dim en As New CultureInfo("en-US")Thread.CurrentThread.CurrentCulture = en
Dim uFile As String = e.Name Dim TheDate As String = DateTime.Now ' ' Pull apart the uFile string which is the full path and file name into ' Folder, Plant and File name only. Path MUST BE Drive\Folder\Plant\File format. Dim sFolder As String Dim sPlant As String Dim sFile As String Dim iUpper As Integer Dim PathPiece() As String = uFile.Split("\")iUpper = UBound(PathPiece)
If iUpper < 2 ThenMsgBox(
"Improper directory structure in watched folder" & vbNewLine & "Structure MUST BE Drive\Folder\Plant\File") End IfsFolder = PathPiece(iUpper - 2)
sPlant = PathPiece(iUpper - 1)
sFile = PathPiece(iUpper)
' ' The Excel file we want to write to Dim XLFile As String = XL_file.Text Dim XLFileCopy As String = XL_file_copy.Text Dim XLSheet As String = sPlant Dim sConnectionString As String = "Provider=Microsoft.Jet.OLEDB.4.0;" _&
"Data Source=" & XLFile _&
";" & "Extended Properties=Excel 8.0;" ' ' This bit opens the spreadsheet, activates the worksheet then finds the actual used rows ' to try to make sure no empty rows show up due to a user manually deleting rows. ' if the empty rows will not go away then try opening the spreadsheet, select the rows, ' then edit, clear contents then delete the rows again. ' Dim oExcel As excel.ApplicationClass Dim oBook As excel.WorkbookClass Dim oBooks As excel.WorkbooksoExcel = CreateObject(
"Excel.Application")oExcel.Visible =
FalseoBooks = oExcel.Workbooks
oBook = oBooks.Open(XLFile)
Dim oSheet As excel.WorksheetoSheet = oBook.Worksheets(XLSheet)
oSheet.Activate()
oBook.ActiveSheet.UsedRange()
'oSheet =
NothingoBook.Close(
False)System.Runtime.InteropServices.Marshal.ReleaseComObject(oBook)
oBook =
NothingSystem.Runtime.InteropServices.Marshal.ReleaseComObject(oBooks)
oBooks =
NothingoExcel.Quit()
System.Runtime.InteropServices.Marshal.ReleaseComObject(oExcel)
oExcel =
NothingGC.Collect()
' Dim Conn1 As New System.Data.OleDb.OleDbConnection(sConnectionString)Conn1.Open()
Dim cmd As New System.Data.OleDb.OleDbCommandcmd.Connection = Conn1
sPlant =
String.Concat(sPlant, "$") If String.Compare(sFolder, "pending", True) = 0 Thencmd.CommandText =
String.Format("INSERT INTO [{0}] (Project, Pending) VALUES(@au_file,@au_date)", sPlant) Elsecmd.CommandText =
String.Format("UPDATE [{0}] Set {1}='{2}' WHERE Project=sFile", sPlant, sFolder, TheDate) End Ifcmd.Parameters.AddWithValue(
"@au_file", sFile)cmd.Parameters.AddWithValue(
"@au_date", TheDate)cmd.ExecuteNonQuery()
Conn1.Close()
' Copy the XLFile so this program does not have to worry about a user keeping the master file openSystem.IO.File.Copy(XLFile, XLFileCopy,
True) End SubEnd
Class