Imports MSN_Live_Log_Manager.LogExplorer
Public Class Form1
Public Structure Contact
Private _Address, _FileName As String
Public Property Address() As String
Get
Return _Address
End Get
Set(ByVal value As String)
_Address = value
End Set
End Property
Public Property FileName() As String
Get
Return _FileName
End Get
Set(ByVal value As String)
_FileName = value
End Set
End Property
Sub New(ByVal File As String)
Me.
Address = IO.
Path.
GetFileNameWithoutExtension(File)
End Sub
Public Overrides Function ToString() As String
Return Me.Address
End Function
End Structure
Private ReceivedFiles As String = My.Computer.FileSystem.SpecialDirectories.MyDocuments & "\File ricevuti"
Private NetProfileDirs As New List(Of String)
Private Contacts As New List(Of Contact)
'Contatti tab
Private LoadedLogs As New List(Of Log)
Private Sub LoadLogs(ByVal Dir As String)
Dim Months() As String = IO.Directory.GetDirectories(Dir)
Dim User As New TreeNode
Dim TempUserList As New List(Of String)
User.Text = IO.Path.GetFileName(Dir)
User.ImageKey = "user"
User.Tag = "user"
For Each Month As String In Months
Dim M As New TreeNode
M.Text = IO.Path.GetFileName(Month)
M.ImageKey = "folder"
M.Tag = "folder"
For Each Log As String In IO.Directory.GetFiles(Month, "*.html")
Dim U As New TreeNode
U.Text = IO.Path.GetFileNameWithoutExtension(Log)
U.ImageKey = "log"
U.Tag = "log"
M.Nodes.Add(U)
If Not TempUserList.Contains(U.Text) Then
Me.Contacts.Add(New Contact(Log))
TempUserList.Add(U.Text)
End If
Next
User.Nodes.Add(M)
Next
trwLogs.Nodes.Add(User)
End Sub
Private Function GetListViewItem(ByVal S As LogExplorer.Session) As ListViewItem
Dim Main As New ListViewItem
Main.Text = S.StartTime.ToLongDateString
With Main.SubItems
.Add(S.StartTime.ToShortTimeString)
If S.StartTime.Date <> S.EndTime.Date Then
.Add(S.EndTime.ToShortTimeString & " di " & S.EndTime.ToLongDateString)
Else
.Add(S.EndTime.ToShortTimeString)
End If
.Add(String.Format("{0} ore, {1} minuti", S.ElapsedTime.Hours, S.ElapsedTime.Minutes))
.Add(S.Messages)
End With
Dim Users As New System.Text.StringBuilder
For I As Int16 = 0 To S.Contacts.Count - 1
If I > 0 Then
Users.Append(", ")
End If
Users.Append(S.Contacts(I))
Next
Main.SubItems.Add(Users.ToString)
Main.Tag = S
Return Main
End Function
Private Function GetListViewItem(ByVal ParamArray Texts() As String) As ListViewItem
Return New ListViewItem(Texts)
End Function
Private Function FormatSpan(ByVal T As TimeSpan) As String
If T.Hours = 0 And T.Days = 0 Then
Return (T.Minutes & " minuti")
ElseIf T.Days = 0 Then
Return (T.Hours & " ore e " & T.Minutes & " minuti")
Else
Return (T.Days & " giorni, " & T.Hours & " ore e " & T.Minutes & " minuti")
End If
End Function
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim Confirm As New System.Text.RegularExpressions.Regex(".+\d{10}")
Dim SubDirs() As String = IO.Directory.GetDirectories(ReceivedFiles)
For Each Dir As String In SubDirs
If Confirm.IsMatch(IO.Path.GetFileName(Dir)) Then
LoadLogs(Dir)
NetProfileDirs.Add(Dir)
End If
Next
For Each C As Contact In Me.Contacts
cmbContacts.Items.Add(C)
Next
cmbContacts.Sorted = True
If NetProfileDirs.Count > 0 Then
txtDir.Text = NetProfileDirs(0) & "\Cronologia"
End If
txtHelp.Text = My.Resources.Help
Me.WindowState = FormWindowState.Maximized
End Sub
Private Sub trwLogs_NodeMouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.TreeNodeMouseClickEventArgs) Handles trwLogs.NodeMouseDoubleClick
Dim Selected As TreeNode = e.Node
If Selected.Tag = "log" Then
Dim FileName As String = ReceivedFiles & "\" & Selected.FullPath & ".html"
Dim Path As String = "file:///" & FileName.Replace("\", "/")
wbShowLog.Navigate(Path)
End If
End Sub
Private Sub btnCalculate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculate.Click
If cmbContacts.SelectedIndex < 0 Then
MessageBox.Show("Selezionare un contatto dalla lista prima!", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Exit Sub
End If
Dim LogFiles As New List(Of String)
For Each Dir As String In NetProfileDirs
LogFiles.AddRange(IO.Directory.GetFiles(Dir, "*.html", IO.SearchOption.AllDirectories))
Next
Dim Sessions As New List(Of LogExplorer.Session)
Dim Index As Int16 = 0
LoadedLogs.Clear()
For Each LogFile As String In LogFiles
If LogFile.Contains(cmbContacts.SelectedItem.ToString) Then
Dim Log As New LogExplorer.Log(LogFile)
Do
Application.DoEvents()
Loop Until Log.IsLoaded
lblStatus.Text = String.Format("{0:N2}% completato", 100 * Index / LogFiles.Count)
Sessions.AddRange(Log.Sessions)
LoadedLogs.Add(Log)
End If
Index += 1
Next
lblStatus.Text = "99.00% completato"
Sessions.Sort(New LogExplorer.SessionByStartTimeComparer())
lblStatus.Text = "Completato"
If Sessions.Count = 0 Then
Exit Sub
End If
lstSessions.Items.Clear()
lstInfo.Items.Clear()
For Each S As LogExplorer.Session In Sessions
lstSessions.Items.Add(GetListViewItem(S))
Next
'Prima/ultima conversazione
'Conversazione più lunga:
'Conversazione più breve:
'Conversazione con più partecipanti:
'Totale ore di conversazione:
'Totale dimensione dei log:
Dim FirstTemp As Session = Sessions(0)
Dim LastTemp As Session = Sessions(0)
Dim MaxTemp As Session = Sessions(0)
Dim MinTemp As Session = Sessions(0)
Dim MaxUserTemp As Session = Sessions(0)
Dim TotalTime As New TimeSpan
Dim TotalSize, TotalMessages As Int32
For Each S As LogExplorer.Session In Sessions
If S.StartTime < FirstTemp.StartTime Then
FirstTemp = S
End If
If S.StartTime > LastTemp.StartTime Then
LastTemp = S
End If
If S.ElapsedTime.TotalSeconds > MaxTemp.ElapsedTime.TotalSeconds Then
MaxTemp = S
End If
If S.ElapsedTime.TotalSeconds < MinTemp.ElapsedTime.TotalSeconds Then
MinTemp = S
End If
If S.Contacts.Count > MaxUserTemp.Contacts.Count Then
MaxUserTemp = S
End If
TotalTime = TotalTime.Add(S.ElapsedTime)
TotalMessages += S.Messages
TotalSize += S.HTML.Length
Next
With lstInfo.Items
.Add(GetListViewItem("Prima conversazione", FirstTemp.ToString))
.Add(GetListViewItem("Ultima conversazione", LastTemp.ToString))
.Add(GetListViewItem("Conversazione più lunga", MaxTemp.ToString & " (" & FormatSpan(MaxTemp.ElapsedTime) & ")"))
.Add(GetListViewItem("Conversazione più corta", MinTemp.ToString & " (" & FormatSpan(MinTemp.ElapsedTime) & ")"))
.Add(GetListViewItem("Conversazione con più partecipanti", MaxUserTemp.ToString & " (" & MaxUserTemp.Contacts.Count & " partecipanti)"))
.Add(GetListViewItem("Totale ore di conversazione", FormatSpan(TotalTime)))
.Add(GetListViewItem("Totale dimensione dei log", String.Format("{0:N0}", TotalSize) & " bytes"))
.Add(GetListViewItem("Totale messaggi", TotalMessages))
End With
End Sub
Private Sub lstSessions_DoubleClick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstSessions.DoubleClick
If lstSessions.SelectedIndices.Count = 0 Then
Exit Sub
End If
Dim Session As LogExplorer.Session = lstSessions.SelectedItems(0).Tag
Dim Window As New Form
Dim Wb As New WebBrowser
Dim HTML As New System.Text.StringBuilder
HTML.
AppendLine(IO.
File.
ReadAllText(Application.
StartupPath & "\LogStyleTemplate.txt"))
HTML.AppendLine("<body>")
HTML.AppendLine(Session.HTML)
HTML.AppendLine("</body></html>")
Window.Text = "Sessione di " & Session.StartTime.ToLongDateString
Window.Size = New Size(640, 480)
Window.StartPosition = FormStartPosition.CenterScreen
Window.Controls.Add(Wb)
Wb.Dock = DockStyle.Fill
Wb.DocumentText = HTML.ToString
Window.ShowDialog()
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnGraphTimePerDay.Click
If LoadedLogs.Count = 0 Then
MessageBox.Show("Scegliere un contatto e caricarne le informazioni prima di procedere!", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Exit Sub
End If
Dim Window As New Form
Dim Graph As New GraphTimePerDay(Log.MergeLogs(LoadedLogs))
Window.Text = "Grafico Tempo di conversazione al giorno"
Window.Size = New Size(700, 400)
Window.StartPosition = FormStartPosition.CenterScreen
Window.Controls.Add(Graph)
Graph.Dock = DockStyle.Fill
Window.ShowDialog()
End Sub
Private Sub btnCalculateGeneral_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculateGeneral.Click
lstGeneralInfo.Items.Clear()
GC.Collect()
Dim LogFiles As New List(Of String)
For Each Dir As String In NetProfileDirs
LogFiles.AddRange(IO.Directory.GetFiles(Dir, "*.html", IO.SearchOption.AllDirectories))
Next
Dim Sessions As New List(Of LogExplorer.Session)
Dim UserLogs
As New Dictionary(Of
String, LogExplorer.
ContactLogInfo)
Dim TotalTime As New TimeSpan
Dim TotalSize, TotalSessionNumber As Int32
Dim ContactNumber, TotalMessages As Int32
Dim MaxSessionContact As New ContactLogInfo
Dim MinSessionContact As New ContactLogInfo
Dim Index As Int16 = 0
For Each LogFile As String In LogFiles
Dim Log As New LogExplorer.Log(LogFile)
Dim LogName As String = IO.Path.GetFileNameWithoutExtension(LogFile)
Do
Application.DoEvents()
Loop Until Log.IsLoaded
Sessions.AddRange(Log.Sessions)
If UserLogs.ContainsKey(LogName) Then
With UserLogs(LogName)
.LogSize += Log.Size
.SessionNumber += Log.Sessions.Count
For Each S As Session In Log.Sessions
.SessionTime = .SessionTime.Add(S.ElapsedTime)
.Messages += S.Messages
Next
.Name = LogName
End With
Else
Dim Info As New ContactLogInfo
Info.LogSize = Log.Size
Info.SessionNumber = Log.Sessions.Count
For Each S As Session In Log.Sessions
Info.SessionTime = Info.SessionTime.Add(S.ElapsedTime)
Info.Messages += S.Messages
Next
Info.Name = LogName
UserLogs.Add(LogName, Info)
End If
TotalSize += Log.Size
For Each S As Session In Log.Sessions
TotalTime = TotalTime.Add(S.ElapsedTime)
TotalMessages += S.Messages
Next
lblStatusGeneral.Text = String.Format("{0:N2}% completato", 70 * Index / LogFiles.Count)
Index += 1
Log = Nothing
Sessions.Clear()
Next
ContactNumber = UserLogs.Keys.Count
Index = 0
MinSessionContact.SessionNumber = 1000
For Each Key As String In UserLogs.Keys
With UserLogs(Key)
lstGeneralInfo.Items.Add(GetListViewItem(Key, String.Format("{0:N0} bytes", .LogSize), FormatSpan(.SessionTime), .SessionNumber, .Messages))
TotalSessionNumber += .SessionNumber
If .SessionNumber > MaxSessionContact.SessionNumber Then
MaxSessionContact = UserLogs(Key)
End If
If .SessionNumber < MinSessionContact.SessionNumber Then
MinSessionContact = UserLogs(Key)
End If
End With
lblStatusGeneral.Text = String.Format("{0:N2}% completato", 70 + 30 * Index / UserLogs.Keys.Count)
Index += 1
Application.DoEvents()
Next
lblTotalMessages.Text = "Totale messaggi: " & TotalMessages
lblTotalTime.Text = "Totale ore di conversazione: " & FormatSpan(TotalTime)
lblTotalSize.Text = "Total dimensione dei log: " & String.Format("{0:N0} bytes", TotalSize)
lblTotalSessions.Text = "Numero di conversazioni totali: " & TotalSessionNumber
lblTotalContacts.Text = "Numero di contatti attivi: " & ContactNumber
lblBestContact.Text = "Contatto col maggiore numero di conversazioni: " & String.Format("{0} ({1})", MaxSessionContact.Name, MaxSessionContact.SessionNumber)
lblWorstContact.Text = "Contatto col minor numero di conversazioni: " & String.Format("{0} ({1})", MinSessionContact.Name, MinSessionContact.SessionNumber)
lblStatusGeneral.Text = "Completato"
btnSaveReport.Visible = True
UserLogs.Clear()
Sessions.Clear()
UserLogs = Nothing
Sessions = Nothing
TotalTime = Nothing
MinSessionContact = Nothing
MaxSessionContact = Nothing
GC.Collect()
End Sub
Private Class lstGeneralInfoColumnComparer
Implements IComparer
Private Index As Int16
Private TimeSpanRegex As New System.Text.RegularExpressions.Regex("((?<Days>\d+) giorni, )?((?<Hours>\d+) ore e )?(?<Minutes>\d+) minuti")
Sub New(ByVal Index As Int16)
Me.Index = Index
End Sub
Private Function IntOrZero(ByVal S As String) As Int32
Dim Result As Int32 = 0
If Int32.TryParse(S, Result) Then
Return Result
Else
Return 0
End If
End Function
Public Function Compare(ByVal x As Object, ByVal y As Object) As Integer Implements System.Collections.IComparer.Compare
Dim L1, L2 As ListViewItem
L1 = DirectCast(x, ListViewItem)
L2 = DirectCast(y, ListViewItem)
Select Case Index
Case 1
Return String.Compare(L1.Text, L2.Text)
Case 2
Dim S1, S2 As Int32
Dim H1 As String = L1.SubItems(1).Text.Replace(" bytes", "").Replace(".", "")
Dim H2 As String = L2.SubItems(1).Text.Replace(" bytes", "").Replace(".", "")
S1 = Int32.Parse(H1)
S2 = Int32.Parse(H2)
Return S1.CompareTo(S2)
Case 3
Dim M1, M2 As System.Text.RegularExpressions.Match
Dim T1, T2 As TimeSpan
M1 = TimeSpanRegex.Match(L1.SubItems(2).Text)
M2 = TimeSpanRegex.Match(L2.SubItems(2).Text)
T1 = New TimeSpan(IntOrZero(M1.Groups("Days").Value), IntOrZero(M1.Groups("Hours").Value), IntOrZero(M1.Groups("Minutes").Value), 0)
T2 = New TimeSpan(IntOrZero(M2.Groups("Days").Value), IntOrZero(M2.Groups("Hours").Value), IntOrZero(M2.Groups("Minutes").Value), 0)
Return TimeSpan.Compare(T1, T2)
Case 4, 5
Return CInt(L1.SubItems(Index - 1).Text).CompareTo(CInt(L2.SubItems(Index - 1).Text))
End Select
End Function
End Class
Private Sub lstGeneralInfo_ColumnClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles lstGeneralInfo.ColumnClick
lstGeneralInfo.ListViewItemSorter = New lstGeneralInfoColumnComparer(e.Column + 1)
End Sub
Private Sub btnSaveReport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSaveReport.Click
Dim Save As New SaveFileDialog
Save.Filter = "Pagina web|*.html"
If Save.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim Writer As New IO.StreamWriter(Save.FileName)
Writer.
WriteLine(IO.
File.
ReadAllText(Application.
StartupPath & "\LogReportTemplate.txt").
Replace("|||Log|||",
"Rapporto MSN Live Log Manager del " & Date.
Now.
ToShortDateString))
Writer.WriteLine("<table style='font-family: ""Segoe UI"",Tahoma, Verdana, sans-serif; font-size:0.95em; color:#333333;' border='0' width='98%'>")
Writer.WriteLine(" <tr class='info'><td>{0}</td></tr>", lblTotalMessages.Text)
Writer.WriteLine(" <tr class='info'><td>{0}</td></tr>", lblTotalTime.Text)
Writer.WriteLine(" <tr class='info'><td>{0}</td></tr>", lblTotalSize.Text)
Writer.WriteLine(" <tr class='info'><td>{0}</td></tr>", lblTotalSessions.Text)
Writer.WriteLine(" <tr class='info'><td>{0}</td></tr>", lblTotalContacts.Text)
Writer.WriteLine(" <tr class='info'><td>{0}</td></tr>", lblBestContact.Text)
Writer.WriteLine(" <tr class='info'><td>{0}</td></tr>", lblWorstContact.Text)
Writer.WriteLine("</table>")
Writer.WriteLine("<br><br>")
Writer.WriteLine("<table style='font-family: ""Segoe UI"",Tahoma, Verdana, sans-serif; font-size:0.95em; color:#333333;' border='0' width='98%'>")
Writer.WriteLine(" <tr class='elem'><td class='odd' width='40%'>Contatto</td><td class='odd' width='15%'>Dimensione log</td><td class='odd' width='15%'>Tempo conversazioni</td><td class='odd' width='15%'>Numero conversazioni</td><td class='odd' width='15%'>Numero messaggi</td></tr>")
Dim Even As Boolean = True
Dim El As New System.Text.StringBuilder
For Each L As ListViewItem In lstGeneralInfo.Items
Writer.WriteLine(" <tr class='elem'><td class='{5}' width='40%'>{0}</td><td class='{5}' width='15%'>{1}</td><td class='{5}' width='15%'>{2}</td><td class='{5}' width='15%'>{3}</td><td class='{5}' width='15%'>{4}</td></tr>", _
L.SubItems(0).Text, L.SubItems(1).Text, L.SubItems(2).Text, L.SubItems(3).Text, L.SubItems(4).Text, IIf(Even, "even", "odd"))
Even = Not Even
Next
Writer.WriteLine("</table></body></html>")
Writer.Close()
End If
End Sub
Private Sub btnCalculateOldGeneral_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCalculateOldGeneral.Click
If Not IO.Directory.Exists(txtDir.Text) Then
MessageBox.Show("La cartella selezionata non esiste!", Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Exit Sub
End If
Dim Index As Int32 = 0
Dim LogFiles() As String = IO.Directory.GetFiles(txtDir.Text, "*.xml", IO.SearchOption.AllDirectories)
Dim TotalTime As New TimeSpan
Dim TotalSize, TotalContacts, TotalSessions, TotalMessages As Int32
lstOldGeneralInfo.Items.Clear()
For Each XmlLog As String In LogFiles
Try
Dim Log As New OldLog(XmlLog)
lstOldGeneralInfo.Items.Add(GetListViewItem(IO.Path.GetFileNameWithoutExtension(XmlLog), String.Format("{0:N0} bytes", Log.Size), FormatSpan(Log.ElapsedTime), Log.Sessions, Log.Messages))
lblOldStatusGeneral.Text = String.Format("{0:N2}", 100 * Index / LogFiles.Length)
Application.DoEvents()
TotalTime = TotalTime.Add(Log.ElapsedTime)
TotalMessages += Log.Messages
TotalSessions += Log.Sessions
TotalSize += Log.Size
TotalContacts += 1
Catch Ex As Exception
End Try
Index += 1
Next
lblOldTotalMessages.Text = "Totale messaggi: " & TotalMessages
lblOldTotalTime.Text = "Totale ore di conversazione: " & FormatSpan(TotalTime)
lblOldTotalSize.Text = "Total dimensione dei log: " & String.Format("{0:N0} bytes", TotalSize)
lblOldTotalSessions.Text = "Numero di conversazioni totali: " & TotalSessions
lblOldContactNumber.Text = "Numero di contatti attivi: " & TotalContacts
lblOldStatusGeneral.Text = "Completato"
btnOldSaveReport.Visible = True
End Sub
Private Sub lstOlgGeneralInfo_ColumnClick(ByVal sender As System.Object, ByVal e As System.Windows.Forms.ColumnClickEventArgs) Handles lstOldGeneralInfo.ColumnClick
lstOldGeneralInfo.ListViewItemSorter = New lstGeneralInfoColumnComparer(e.Column + 1)
End Sub
Private Sub btnBrowse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnBrowse.Click
Dim Folder As New FolderBrowserDialog
Folder.
Description = "Selezionare la cartella Cronologia all'interno del proprio profilo in Documenti\File ricevuti."
If Folder.
ShowDialog = Windows.
Forms.
DialogResult.
OK Then
txtDir.
Text = Folder.
SelectedPath
End If
End Sub
Private Sub btnOldSaveReport_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOldSaveReport.Click
Dim Save As New SaveFileDialog
Save.Filter = "Pagina web|*.html"
If Save.ShowDialog = Windows.Forms.DialogResult.OK Then
Dim Writer As New IO.StreamWriter(Save.FileName)
Writer.
WriteLine(IO.
File.
ReadAllText(Application.
StartupPath & "\LogReportTemplate.txt").
Replace("|||Log|||",
"Rapporto MSN Live Log Manager del " & Date.
Now.
ToShortDateString))
Writer.WriteLine("<table style='font-family: ""Segoe UI"",Tahoma, Verdana, sans-serif; font-size:0.95em; color:#333333;' border='0' width='98%'>")
Writer.WriteLine(" <tr class='info'><td>{0}</td></tr>", lblOldTotalMessages.Text)
Writer.WriteLine(" <tr class='info'><td>{0}</td></tr>", lblOldTotalTime.Text)
Writer.WriteLine(" <tr class='info'><td>{0}</td></tr>", lblOldTotalSize.Text)
Writer.WriteLine(" <tr class='info'><td>{0}</td></tr>", lblOldTotalSessions.Text)
Writer.WriteLine(" <tr class='info'><td>{0}</td></tr>", lblOldContactNumber.Text)
Writer.WriteLine("</table>")
Writer.WriteLine("<br><br>")
Writer.WriteLine("<table style='font-family: ""Segoe UI"",Tahoma, Verdana, sans-serif; font-size:0.95em; color:#333333;' border='0' width='98%'>")
Writer.WriteLine(" <tr class='elem'><td class='odd' width='40%'>Contatto</td><td class='odd' width='15%'>Dimensione log</td><td class='odd' width='15%'>Tempo conversazioni</td><td class='odd' width='15%'>Numero conversazioni</td><td class='odd' width='15%'>Numero messaggi</td></tr>")
Dim Even As Boolean = True
Dim El As New System.Text.StringBuilder
For Each L As ListViewItem In lstOldGeneralInfo.Items
Writer.WriteLine(" <tr class='elem'><td class='{5}' width='40%'>{0}</td><td class='{5}' width='15%'>{1}</td><td class='{5}' width='15%'>{2}</td><td class='{5}' width='15%'>{3}</td><td class='{5}' width='15%'>{4}</td></tr>", _
L.SubItems(0).Text, L.SubItems(1).Text, L.SubItems(2).Text, L.SubItems(3).Text, L.SubItems(4).Text, IIf(Even, "even", "odd"))
Even = Not Even
Next
Writer.WriteLine("</table></body></html>")
Writer.Close()
End If
End Sub
Private Sub btnAbout_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAbout.Click
My.Forms.The_Lair_AboutBox1.ShowDialog()
End Sub
End Class