|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
IntroductionA friend, developing an application in VB 6.0 needed a solution with the following requirements:
The answer was: Windows Services. What does the application do?The application that generated this solution uploads mdb access files zipped into a file to decrease the size of the data base file, 'cause some of his clients use 56k modem connections. When developing his application in ASP.NET, he needed some way to monitor directory for this special zipped files. As the files arrive, the solution must unzip the files and overwrite the file content in the same directories. The easiest way to do this, we thought, was with VB 6. We started to look for some place to find information of how doing this in VB 6, but no success. Every article, tutorial and code I found used VB.NET, C# or any other .NET language. We were convinced that VB.NET had to be the choice for developing the Windows service. Were fascinated with how easy is to build a Windows service with VB.NET. With VB 6, we tried to build a normal executable and run it against a series of tools (as many articles describe) but none of the tools did the job. With VB.NET we only inherited from the In the beginning, I was using the D# IDE which has no facilities to build a Windows service, I had to manually type the definitions for the methods and so. I tried to set the The InstallerThe installer does nothing but to install the Windows service. We detected that the 'Open the HKEY_LOCAL_MACHINE\SYSTEM key
rgkSystem = Microsoft.Win32.Registry.LocalMachine.OpenSubKey("System")
'Open CurrentControlSet
rgkCurrentControlSet = rgkSystem.OpenSubKey("CurrentControlSet")
'Go to the services key
rgkServices = rgkCurrentControlSet.OpenSubKey("Services")
'Open the key for your service, and allow writing
rgkService = rgkServices.OpenSubKey(si.ServiceName, True)
'Add your service's description as a REG_SZ value named "Description"
rgkService.SetValue("Description", m_Description)
'(Optional) Add some custom information your service will use...
rgkConfig = rgkService.CreateSubKey("Parameters")
rgkConfig.Close()
rgkService.Close()
rgkCurrentControlSet.Close()
rgkSystem.Close()
The approachWe used a timer object to monitor the directories listed in a .ini file in every three seconds. <System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponents()
Me.timer1 = New System.Timers.Timer()
Me.timer1.Interval = 3000
Me.timer1.Enabled = True
Me.ServiceName = "CheckWebDataBase"
End Sub
In the Protected Overrides Sub OnStart(ByVal args() As String)
' TODO: Add start code here (if required)
' to start your service.
Me.timer1.Enabled = True
End Sub
Protected Overrides Sub OnStop()
' TODO: Add tear-down code here (if required)
' to stop your service.
Me.timer1.Enabled = False
End Sub
The timer elapsed event is listed below: Private Sub Timer1Elapsed(ByVal sender As System.Object, _
ByVal e As System.Timers.ElapsedEventArgs) _
Handles timer1.Elapsed
Dim qt As Integer, x As Integer
Dim path As String = "c:\windows"
Dim folder As String, date_ As String, ZIP As String
Dim INIFile As String = path & "\Customer.ini"
qt = CType(CheckWebDataBaseService.Ini.ReadIni(INIFile, _
"General", "Number"), System.Int32)
For x = 1 To qt
folder = CheckWebDataBaseService.Ini.ReadIni(INIFile, "Folders", x)
'Zip File name ZIP = folder & "DataBase.zip"
date_ = CStr(FileDateTime(ZIP))
If CheckWebDataBaseService.Ini.ReadIni(INIFile, "Dates", x) <> date_ Then
Me.ExtractArchive(ZIP, folder)
CheckWebDataBaseService.Ini.WriteIni(INIFile, "Dates", x, date_)
End If
Next
End Sub
We used the ini approach for the usability, 'cause it's easy to add new customers. Note that the name of the zipped file is hard-coded as "DataBase.zip" See the contents for Customer.ini: [General]
Number=2
[Folders]
1=c:\dev\test\
2=c:\dev\test2\
[Dates]
1=6/1/2005 10:40:19
2=6/1/2005 10:25:49
In Number, we have the numbers of customers. In Folders, we have the customers' folders. And in Dates, we have the last updated date of the file in the folder. To unzip the files, we have used the excellent library SharpZipLib from ICsharpCode (the same for the SharpDevelop or #D). Public Sub ExtractArchive(ByVal zipFilename As String, ByVal ExtractDir As String)
Dim Redo As Integer = 1
Dim MyZipInputStream As ZipInputStream
Dim MyFileStream As FileStream
MyZipInputStream = New ZipInputStream(New FileStream(zipFilename, _
FileMode.Open, FileAccess.Read))
Dim MyZipEntry As ZipEntry = MyZipInputStream.GetNextEntry
Directory.CreateDirectory(ExtractDir)
While Not MyZipEntry Is Nothing
If (MyZipEntry.IsDirectory) Then
Directory.CreateDirectory(ExtractDir & "\" & MyZipEntry.Name)
Else
If Not Directory.Exists(ExtractDir & "\" & _
Path.GetDirectoryName(MyZipEntry.Name)) Then
Directory.CreateDirectory(ExtractDir & "\" & _
Path.GetDirectoryName(MyZipEntry.Name))
End If
MyFileStream = New FileStream(ExtractDir & "\" & _
MyZipEntry.Name, FileMode.OpenOrCreate, FileAccess.Write)
Dim count As Integer
Dim buffer(4096) As Byte
count = MyZipInputStream.Read(buffer, 0, 4096)
While count > 0
MyFileStream.Write(buffer, 0, count)
count = MyZipInputStream.Read(buffer, 0, 4096)
End While
MyFileStream.Close()
End If
Try
MyZipEntry = MyZipInputStream.GetNextEntry
Catch ex As Exception
MyZipEntry = Nothing
End Try
End While
If Not (MyZipInputStream Is Nothing) Then MyZipInputStream.Close()
If Not (MyFileStream Is Nothing) Then MyFileStream.Close()
End Sub
End Class
Screenshots
EndingAnd that's all. We hope you find this code useful. FutureWe plan to substitute ini files for config files. If anyone do it for me, please keep me updated. ThanksTo Nirondes for the idea to build that Windows service. I am sure we learned too much.
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||