Introduction
Whenever we develop software, we need automatic updating. This allows the developer to take advantage of automatic resources through an open source library developed 100% in VB.NET and can be used in C # and other languages.
So in this article, I propose a library (.dll), which is based on the AntSoft Systems On Demand (ASUpdater) library (I am licensed to distribute this code because I am the author of it and CEO of the company).
Requirements
- .NET Framework 4.5 or higher
System.Windows.Forms
System.Reflection
System.Xml
System.Security.Cryptography
System.ComponentModel
System.Drawing
Code of the Library
Module
The module has basic and common library functions, as well as application information such as Path
, Title
, and Versions
.
In this module, we have the variables, which will receive the application data and the functions UrlExist
, GotInternet
, CreateHashPure
, GetMd5Hash
and sub
MainLib
.
In module mMain
, we have the following code:
1 Imports System.Windows.Forms
2 Imports System.Net
3 Imports System.Xml
4 Imports System.Text
5 Imports System.Text.RegularExpressions
6 Imports System.Security.Cryptography
7 Imports System.ComponentModel
8 Imports System.Drawing
9 Module mMain
10 Public sPath As String
11 Public sTitle As String
12 Public sVerActual As String
13 Public sVerActualSimp As String
14
15
16
17 Public sVerUpdate As FileVersionInfo = _
18 FileVersionInfo.GetVersionInfo(Application.ExecutablePath)
19 Public sVersion As String
20 Public PicUpdateImg As System.Drawing.Image
21 Public PicAboutImg As System.Drawing.Image
22 Public LibUpdate As New Updater
23
24 Public Sub MainLib()
25
26 If Application.StartupPath.EndsWith("\") Then
27 sPath = Application.StartupPath
28 Else
29 sPath = Application.StartupPath & "\"
30 End If
31
32 PicUpdateImg = My.Resources.ASSUpdater
33
34 PicAboutImg = My.Resources.ASSUpdaterAbout
35
36 With My.Application.Info
37 sTitle = .ProductName.ToString & " v" & .Version.Major & "." & .Version.Minor
38 sVerActual = .Version.Major.ToString
39 sVerActualSimp = String.Format("{0}.{1}", _
40 .Version.Major.ToString, .Version.Minor.ToString)
41 sVersion = String.Format("Versão {0}", My.Application.Info.Version.ToString)
42 End With
43 End Sub
44 Public Function UrlExist(ByVal sUrl As String) As Boolean
52 Dim fileUrl As Uri = New Uri(sUrl)
53 Dim req As System.Net.WebRequest
54 req = System.Net.WebRequest.Create(sUrl)
55 Dim resp As System.Net.WebResponse
56 Try
57 resp = req.GetResponse()
58 resp.Close()
59 req = Nothing
60 Return (True)
61 Catch ex As Exception
62 req = Nothing
63 Return False
64 End Try
65 End Function
66 Public Function GotInternet() As Boolean
72 Try
73 Return My.Computer.Network.IsAvailable
74 Catch weberrt As WebException
75 Return False
76 Catch except As Exception
77 Return False
78 End Try
79 End Function
80 Public Function CreateHashPure(ByVal sString As String, _
89 Optional iSize As Integer = 32) As String
90 Using md5Hash As MD5 = MD5.Create()
91 Dim hash As String = GetMd5Hash(md5Hash, sString)
92 hash = Left(hash, iSize)
93 Return LCase(hash)
94 End Using
95 End Function
96 Public Function GetMd5Hash(ByVal md5Hash As MD5, ByVal input As String) As String
104
105
106 Dim data As Byte() = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input))
107
108
109
110 Dim sBuilder As New StringBuilder()
111
112
113
114 Dim i As Integer
115 For i = 0 To data.Length - 1
116 sBuilder.Append(data(i).ToString("x2"))
117 Next i
118
119
120 Return sBuilder.ToString()
121
122 End Function
123
124 End Module
Class
The library has a class named Updater.vb. In this module class, many functions are implemented. This is the heart of the Library, with Functions, Subs and Property. The most important function, which the other, maybe is CheckNewVersion()
, which checks if there is a new version to download and returns a boolean response. With base in this response, it's possible to know if the application needs the update.
Other functions and property, as well as Sub
s, are important because they are part of the library, but they complement other Function
s or even Sub
s. Below is the commented and complete code of the Class
, so that the developer can better understand it.
Imports System.Windows.Forms
Imports System.Reflection
Imports System.Xml
Imports System.IO
Public Class Updater
Private _versionapp As String
Private _codeapp As String
Private _nameapp As String
Private _urlconfig As String
Private sNewVersion As String, sDescUpdate As String, sDateUpdate As String
Public Enum CheckResponse
res_empty = 0
res_noupdate = 1
res_update = 2
res_erro = 3
End Enum
Public Sub New()
MainLib()
End Sub
Public Sub AppUpdate()
Dim frm As New frmUpdateDesc
frm.wbDescription.DocumentText = My.Resources.HTMLStart & _
"<h4>A new version is available for download.</h4>" &
"<p>Version: " & sNewVersion & "<br/>" &
"Date: " & sDateUpdate & "</p>" &
"<div>Description: " & sDescUpdate & "</div>" &
"<p>You want to get the new version now?<br/>" &
"To start the download, click the Download button.!</p>" & My.Resources.HTMLEnd
frm.ShowDialog()
End Sub
Public Sub CheckUpdate()
Dim CheckUpdataRes As CheckResponse = CheckNewVersion()
If CheckUpdataRes = CheckResponse.res_update Then
AppUpdate()
ElseIf CheckUpdataRes = CheckResponse.res_noupdate Then
MessageBox.Show("Your software has the latest version and is up to date!", _
sTitle, MessageBoxButtons.OK, MessageBoxIcon.Information)
ElseIf CheckUpdataRes = CheckResponse.res_empty Then
Exit Sub
ElseIf CheckUpdataRes = CheckResponse.res_erro Then
MessageBox.Show("Could not check for update!", sTitle, _
MessageBoxButtons.OK, MessageBoxIcon.Error)
Else
MessageBox.Show("Error!", sTitle, MessageBoxButtons.OK, MessageBoxIcon.Error)
End If
End Sub
Public Function CheckNewVersion() As CheckResponse
Dim PathTemp As String
PathTemp = System.IO.Path.GetTempPath()
Try
If String.IsNullOrWhiteSpace(URLConfig) Then
MessageBox.Show("You must specify the configuration file path to check _
for update!", sTitle, MessageBoxButtons.OK, MessageBoxIcon.Information)
Return CheckResponse.res_empty
End If
If String.IsNullOrWhiteSpace(VersionApp) Then
MessageBox.Show("Application version must be specified to check _
for update!", sTitle, MessageBoxButtons.OK, MessageBoxIcon.Information)
Return CheckResponse.res_empty
End If
If String.IsNullOrWhiteSpace(NameApp) Then
MessageBox.Show("You must specify the application name to check _
for updates.!", sTitle, MessageBoxButtons.OK, MessageBoxIcon.Information)
Return CheckResponse.res_empty
End If
If GotInternet() = False Then
MessageBox.Show("Unable to check software update. _
No Internet connection verified!", sTitle, _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
Return False
End If
If UrlExist(URLConfig) = True Then
If File.Exists(PathTemp & My.Application.Info.AssemblyName & ".xml") _
Then File.Delete(PathTemp & My.Application.Info.AssemblyName & ".xml")
My.Computer.Network.DownloadFile(URLConfig, PathTemp & _
My.Application.Info.AssemblyName & ".xml")
GoTo InitialDld
Else
Return CheckResponse.res_erro
End If
InitialDld:
Clipboard.SetText(PathTemp & My.Application.Info.AssemblyName & ".xml")
If System.IO.File.Exists(PathTemp & My.Application.Info.AssemblyName & ".xml") Then
Dim dom As New XmlDocument()
dom.Load(PathTemp & My.Application.Info.AssemblyName & ".xml")
Dim sVer As String = dom.SelectSingleNode("//Info/Version").InnerText
Dim sDate As String = dom.SelectSingleNode("//Info/Date").InnerText
Dim sFileDld As String = dom.SelectSingleNode("//Info/Filename").InnerText
Dim sDescription As String = _
dom.SelectSingleNode("//Info//Description").InnerText
If sVerUpdate.FileVersion.ToString < sVer Then
sNewVersion = sVer
sDescUpdate = sDescription
sDateUpdate = sDate
LibUpdate.NameApp = NameApp
LibUpdate.VersionApp = VersionApp
LibUpdate.URLConfig = URLConfig
Return CheckResponse.res_update
Else
Return CheckResponse.res_noupdate
End If
Else
Return CheckResponse.res_erro
End If
Catch ex As Exception
MessageBox.Show("Error: " & ex.Message & vbNewLine & vbNewLine & _
"StackTrace: " & ex.StackTrace, sTitle, MessageBoxButtons.OK, _
MessageBoxIcon.Stop)
Return CheckResponse.res_erro
Finally
End Try
End Function
Public Function LibVersion() As String
Dim assy As System.Reflection.Assembly = GetType(Updater).Assembly
Dim assyName As String = assy.GetName().Name
Dim attr As Attribute = Attribute.GetCustomAttribute( _
assy, GetType(AssemblyTitleAttribute))
Dim adAttr As AssemblyTitleAttribute = _
CType(attr, AssemblyTitleAttribute)
Return String.Format("{0}", GetType(Updater).Assembly.GetName().Version)
End Function
Public Function LibNameVersion() As String
Dim assy As System.Reflection.Assembly = GetType(Updater).Assembly
Dim assyName As String = assy.GetName().Name
Dim attr As Attribute = Attribute.GetCustomAttribute( _
assy, GetType(AssemblyTitleAttribute))
Dim adAttr As AssemblyTitleAttribute = _
CType(attr, AssemblyTitleAttribute)
Return String.Format("{0} v{1}", adAttr.Title, _
GetType(Updater).Assembly.GetName().Version)
End Function
Public Function LibDescription() As String
Dim assy As System.Reflection.Assembly = GetType(Updater).Assembly
Dim assyName As String = assy.GetName().Name
Dim attr As Attribute = Attribute.GetCustomAttribute( _
assy, GetType(AssemblyDescriptionAttribute))
Dim adAttr As AssemblyDescriptionAttribute = _
CType(attr, AssemblyDescriptionAttribute)
Return String.Format("{0}", adAttr.Description)
End Function
Public Function LibName() As String
Dim assy As System.Reflection.Assembly = GetType(Updater).Assembly
Dim assyName As String = assy.GetName().Name
Dim attr As Attribute = Attribute.GetCustomAttribute( _
assy, GetType(AssemblyTitleAttribute))
Dim adAttr As AssemblyTitleAttribute = _
CType(attr, AssemblyTitleAttribute)
Return String.Format("{0}", adAttr.Title)
End Function
Public Function LibCopyright() As String
Dim assy As System.Reflection.Assembly = GetType(Updater).Assembly
Dim assyName As String = assy.GetName().Name
Dim attr As Attribute = Attribute.GetCustomAttribute( _
assy, GetType(AssemblyCopyrightAttribute))
Dim adAttr As AssemblyCopyrightAttribute = _
CType(attr, AssemblyCopyrightAttribute)
Return String.Format("{0}", adAttr.Copyright)
End Function
Public Property VersionApp() As String
Get
Return _versionapp
End Get
Set(value As String)
_versionapp = value
End Set
End Property
Public Property NameApp() As String
Get
Return _nameapp
End Get
Set(value As String)
_nameapp = value
End Set
End Property
Public Property URLConfig() As String
Get
Return _urlconfig
End Get
Set(value As String)
_urlconfig = value
End Set
End Property
End Class
Configuration XML File Structure
The structure of the XML file is important so that the library and its CheckNewVersion ()
function can read the information correctly and then pass the library variables, which will process the information and decide whether or not to update the software.
Below, we provide the structure of XML, which may have the name the developer wants, but it is recommended to be the same as AssemblyName
, to facilitate the update management process if this library is used in multiple projects.
="1.0"="utf-8"
<Application>
<Info>
<Version>1.1.1.0321</Version>
<Date>27/09/2019</Date>
<Filename>http://antsoft.com.br/appsetup.exe</Filename>
<Description>
System Update Tool Improvement.
</Description>
<copyright>Copyright © 2019, AntSoft Systems On Demand</copyright>
</Info>
</Application>
Forms
The three forms in the library project are in the code available for download and will not be discussed in the article, since it is simple to understand because the code is all commented. Just note that in the form, there is a sub
named UpdateService()
, which is the core of the form, because this Sub
is that, after checking the need for update, the library will download the configuration file in XML and after the installation file, which should preferably be exe or msi extension.
The following are the images of the two library forms. The first image is the Update Description Form, the second image is the Update Form, where the installation file will be obtained and then run to install the new version. In the example, the update file is not found because it is a demo.
In the frmUpdater Form
, the Sub
UpdateService()
has an important point to explain, as it allows a better understanding of the developer:
Public Sub UpdateService()
lvwUpdate.Items.Clear()
lvwUpdate.Items.Add("Starting the upgrade", 3)
Try
AddHandler wc.DownloadProgressChanged, AddressOf OnDownloadProgressChanged
AddHandler wc.DownloadFileCompleted, AddressOf OnFileDownloadCompleted
AddTextlvw("Checking for new version online...")
If File.Exists(PathTemp & My.Application.Info.AssemblyName & ".xml") _
Then File.Delete(PathTemp & My.Application.Info.AssemblyName & ".xml")
My.Computer.Network.DownloadFile(UpdaterApp.LibUpdate.URLConfig, _
PathTemp & My.Application.Info.AssemblyName & ".xml")
If File.Exists(PathTemp & My.Application.Info.AssemblyName & ".xml") Then
AddTextlvw("Valid update found ...", 2)
Else
AddTextlvw("Update not verified or process failed!", 1)
AddTextlvw("Try again!", 1)
Exit Sub
pBar.Visible = False
End If
AddTextlvw("Starting version checking ...")
Dim dom As New XmlDocument()
dom.Load(PathTemp & My.Application.Info.AssemblyName & ".xml")
sNewVersion = dom.SelectSingleNode("//Info/Version").InnerText
Dim sDate As String = dom.SelectSingleNode("//Info/Date").InnerText
Dim sFileDld As String = dom.SelectSingleNode("//Info/Filename").InnerText
Dim sFileTmp As String = System.IO.Path.GetFileName(sFileDld)
sFileExec = System.IO.Path.GetFileName(sFileDld)
AddTextlvw("Current version: " & sVerUpdate.FileVersion, 5)
AddTextlvw("Downloadable Version: " & sNewVersion, 5)
If sVerUpdate.FileVersion.ToString < sNewVersion Then
AddTextlvw("Starting the update file download.", 3)
If System.IO.File.Exists(PathTemp & "\" & sFileTmp) Then _
Kill(PathTemp & "\" & sFileTmp)
If UrlExist(sFileDld) = True Then
AddTextlvw("Downloading the installation file...")
wc.DownloadFileAsync(New Uri(sFileDld), PathTemp & "\" & sFileTmp)
Else
AddTextlvw("Setup file not found!", 1)
pBar.Visible = False
Exit Sub
End If
Else
AddTextlvw("No need to update.", 4)
pBar.Visible = False
btnAbout.Enabled = True
End If
Catch ex As Exception
MessageBox.Show("Unable to update software. Error: " & vbNewLine & _
ex.Message, sTitle, _
MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
AddTextlvw("Error trying to verify update.", 1)
pBar.Visible = False
End Try
End Sub
Call UpdateApp Library
To call the new version, check function and then start the download if there is a new version available. It is very simple and done in a few command lines. You must reference the UpdateApp
Library in the project references.
In a form, you need to enter the following command lines:
Public Class Form1
Dim LibUpdater As New UpdaterApp.Updater
Private Sub Button1_Click(sender As Object, e As EventArgs) _
Handles Button1.Click, LinkLabel1.Click
With LibUpdater
.URLConfig = "http://www.antsoft.com.br/CPTests/UpdateApp/" & _
My.Application.Info.AssemblyName & ".xml"
.NameApp = My.Application.Info.ProductName
.VersionApp = My.Application.Info.Version.ToString
.CheckUpdate()
End With
End Sub
End Class
Points of Interest
With the above code, it is possible to check a simple, yet efficient way to check for new updates of your application and it can make it easy for all your customers to get news and make it easy to maintain your software, thus optimizing time and allowing more time to devote to developing new versions.
History
This code is the release version.