Rob van der Woude's Scripting Pages
Powered by GeSHi

Source code for updatecheck.vbs

(view source code of updatecheck.vbs as plain text)

  1. Option Explicit
  2.  
  3. Dim arrAllProgs
  4. Dim blnAll, blnList, blnPopups, blnVerbose
  5. Dim i, intValidArgs
  6. Dim objFSO
  7. Dim strINI, strProg
  8. Dim urlDownload
  9.  
  10. ' Check command line arguments
  11. With WScript.Arguments
  12. 	intValidArgs = 0
  13. 	blnAll       = False
  14. 	blnList      = False
  15. 	blnPopups    = True
  16. 	blnVerbose   = False
  17. 	If .Unnamed.Count > 0 Then
  18. 		strProg      = .Unnamed(0)
  19. 		intValidArgs = intValidArgs + 1
  20. 	End If
  21. 	If .Named.Exists( "A" ) Or .Named.Exists( "All" ) Then
  22. 		blnAll       = True
  23. 		intValidArgs = intValidArgs + 1
  24. 	End If
  25. 	If .Named.Exists( "L" ) Or .Named.Exists( "List" ) Then
  26. 		If .Count <> 1 Then Syntax
  27. 		blnList      = True
  28. 		intValidArgs = intValidArgs + 1
  29. 	End If
  30. 	If .Named.Exists( "NP" ) Or .Named.Exists( "NoPopup" ) Then
  31. 		blnPopups    = False
  32. 		intValidArgs = intValidArgs + 1
  33. 	End If
  34. 	If .Named.Exists( "V" ) Or .Named.Exists( "Verbose" ) Then
  35. 		blnVerbose   = True
  36. 		intValidArgs = intValidArgs + 1
  37. 	End If
  38. 	If .Unnamed.Count > 0 And ( blnList Or blnAll ) Then Syntax
  39. 	If .Unnamed.Count = 0 And Not ( blnAll Or blnList ) Then Syntax
  40. 	If intValidArgs <> .Count Then Syntax
  41. End With
  42.  
  43. ' Check if UpdateCheck.ini exists
  44. Set objFSO = CreateObject( "Scripting.FileSystemObject" )
  45. strINI = Replace( WScript.ScriptFullName, ".vbs", ".ini" )
  46. If Not objFSO.FileExists( strINI ) Then
  47. 	WScript.Echo vbCrLf & "ERROR:" & vbTab & "INI file not found."
  48. 	Set objFSO = Nothing
  49. 	Syntax
  50. End If
  51.  
  52. Set objFSO = Nothing
  53.  
  54. If blnList Then
  55. 	ListProgs strINI, True
  56. 	WScript.Quit 0
  57. Else
  58. 	If blnAll Then
  59. 		arrAllProgs = ListProgs( strINI, False )
  60. 		For i = 0 To UBound( arrAllProgs )
  61. 			CheckProg arrAllProgs(i)
  62. 		Next
  63. 	Else
  64. 		CheckProg strProg
  65. 	End If
  66. End If
  67.  
  68.  
  69. Sub CheckProg( myProg )
  70. 	Dim objFSO, wshShell
  71. 	Dim strExec, strExec2, strLatest, strName, strPath, strPrompt, strRegPath, strRegPath2, strRegVersion, strRegVersion2, strTitle, strVersion
  72.  
  73. 	Set wshShell = CreateObject( "Wscript.Shell" )
  74. 	Set objFSO   = CreateObject( "Scripting.FileSystemObject" )
  75.  
  76. 	' Read values for specified program from UpdateCheck.ini
  77. 	strName        = ReadIni( strINI, myProg, "ProgName" )
  78. 	strRegPath     = wshShell.ExpandEnvironmentStrings( ReadIni( strINI, myProg, "RegPath"  ) )
  79. 	strRegPath2    = wshShell.ExpandEnvironmentStrings( ReadIni( strINI, myProg, "RegPath2" ) )
  80. 	strRegVersion  = ReadIni( strINI, myProg, "RegVersion"  )
  81. 	strRegVersion2 = ReadIni( strINI, myProg, "RegVersion2" )
  82. 	strExec        = wshShell.ExpandEnvironmentStrings( ReadIni( strINI, myProg, "Executable"  ) )
  83. 	strExec2       = wshShell.ExpandEnvironmentStrings( ReadIni( strINI, myProg, "Executable2" ) )
  84. 	urlDownload    = ReadIni( strINI, myProg, "WebSiteDownload" )
  85. 	If Not objFSO.FileExists( strExec ) And strExec2 <> "" Then strExec = strExec2
  86. 	If strExec       = "" Then strExec       = strExec2
  87. 	If strRegPath    = "" Then strRegPath    = strRegPath2
  88. 	If strRegVersion = "" Then strRegVersion = strRegVersion2
  89. 	If strRegVersion = "" Then
  90. 		If strRegPath <> "" Then
  91. 			On Error Resume Next
  92. 			strPath = wshShell.RegRead( strRegPath )
  93. 			If Err Then
  94. 				strPath = wshShell.RegRead( strRegPath2 )
  95. 			End If
  96. 			On Error Goto 0
  97. 			strExec = objFSO.BuildPath( strPath, strExec )
  98. 			If Not objFSO.FileExists( strExec ) And strExec2 <> "" Then strExec = objFSO.BuildPath( strPath, strExec2 )
  99. 		End If
  100. 		If strExec = "" Then
  101. 			WScript.Echo vbCrLf & "ERROR:" & vbTab & "Program path of """ & strName & """ not specified."
  102. 			Set objFSO = Nothing
  103. 			Exit Sub
  104. 		End If
  105. 		If Not objFSO.FileExists( strExec ) Then
  106. 			WScript.Echo vbCrLf & "ERROR:" & vbTab & "Program executable of """ & strName & """ not found."
  107. 			Set objFSO = Nothing
  108. 			Exit Sub
  109. 		End If
  110. 		strVersion = objFSO.GetFileVersion( strExec )
  111. 	Else
  112. 		On Error Resume Next
  113. 		strVersion = wshShell.RegRead( strRegVersion )
  114. 		If Err Then
  115. 			strVersion = wshShell.RegRead( strRegVersion2 )
  116. 		End If
  117. 		On Error Goto 0
  118. 	End If
  119. 	If Strip( strVersion ) = "" Then
  120. 		WScript.Echo vbCrLf & "ERROR:" & vbTab & "Unable to detect the current version of """ & strName & """ ."
  121. 		Set wshShell = Nothing
  122. 		Set objFSO   = Nothing
  123. 		Exit Sub
  124. 	End If
  125.  
  126. 	strLatest  = GetVersion( myProg )
  127.  
  128. 	' /V switch requires display of intermediate results
  129. 	If blnVerbose Then
  130. 		WScript.Echo vbCrLf _
  131. 		           & "Currently installed version : " & strVersion & vbCrLf _
  132. 		           & "Latest available version    : " & strLatest
  133. 	End If
  134.  
  135. 	' Rather complex looking comparison, because sometimes an extra ".0" is appended, and we don't want to make that break the comparison
  136. 	If Left( strVersion, Min( Len( strLatest ), Len( strVersion ) ) ) = Left( strLatest, Min( Len( strLatest ), Len( strVersion ) ) ) Then
  137. 		WScript.Echo """" & strName & """ " & strVersion & " is up-to-date"
  138. 	Else
  139. 		If blnVerbose Then
  140. 			WScript.Echo "UPDATE:" & vbTab & "A new version is available for """ & strName & """"
  141. 		Else
  142. 			WScript.Echo "UPDATE:" & vbTab & "A new version (" & strLatest & ") is available for """ & strName & """ (" & strVersion & " installed)"
  143. 		End If
  144. 		If blnPopups Then
  145. 			strPrompt = "Version " & strLatest & " of """ & strName & """ is newer than the installed " & strVersion & " version." _
  146. 			          & vbCrLf & vbCrLf _
  147. 			          & "Do you want to download the latest version?"
  148. 			strTitle  = "Update available"
  149. 			If MsgBox( strPrompt, vbYesNoCancel, strTitle ) = vbYes Then
  150. 				wshShell.Run urlDownload
  151. 			End If
  152. 		End If
  153. 	End If
  154.  
  155. 	Set wshShell = Nothing
  156. 	Set objFSO   = Nothing
  157. End Sub
  158.  
  159.  
  160. ' Get the latest available version
  161. Function GetVersion( myProg )
  162. 	Dim objHTTP, objMatch, objRE
  163. 	Dim strHTML, strPattern, strUserAgent, strVersion
  164. 	Dim urlCheck
  165. 	' Initial return string, in case an error occurs
  166. 	strVersion = "999999"
  167. 	' Read the required web page URL and regex pattern from the INI file
  168. 	urlCheck   = ReadIni( strINI, myProg, "WebSiteVersion" )
  169. 	strPattern = ReadIni( strINI, myProg, "RegExPattern" )
  170. 	' Use WinHTTP to read the text from the specified web page
  171. 	Set objHTTP = CreateObject( "WinHttp.WinHttpRequest.5.1" )
  172. 	objHTTP.Open "GET", urlCheck, False
  173. 	strUserAgent = "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.3) Gecko/2008092417 Firefox/3.0.3"
  174. 	objHTTP.SetRequestHeader "UserAgent", strUserAgent
  175. 	objHTTP.Send
  176. 	If objHTTP.Status = 200 Then
  177. 		' If the page was returned, use a regular expression to extract the program's current version number
  178. 		strHTML = objHTTP.ResponseText
  179. 		Set objRE = New RegExp
  180. 		objRE.Pattern    = strPattern
  181. 		objRE.IgnoreCase = False
  182. 		objRE.Global     = True
  183. 		Set objMatch = objRE.Execute( strHTML )
  184. 		If objMatch.Count > 0 Then
  185. 			For Each objMatch In objMatch.Item(0).Submatches
  186. 				strVersion = objMatch
  187. 			Next
  188. 		End If
  189. 		' Remove leading zeroes
  190. 		strVersion = Replace( strVersion, "(", "" )
  191. 		strVersion = Replace( strVersion, ")", "" )
  192. 		strVersion = Replace( strVersion, " ", "." )
  193. 		strVersion = Replace( strVersion, ".0", "." )
  194. 		strVersion = Replace( strVersion, "..", ".0." )
  195. 		strVersion = Replace( strVersion, "..", ".0." )
  196. 		If Right( strVersion, 1 ) = "." Then strVersion = strVersion & "0"
  197. 		Set objMatch = Nothing
  198. 		Set objRE = Nothing
  199. 		Set objHTTP = Nothing
  200. 	Else
  201. 		If blnVerbose Then
  202. 			WScript.Echo "ERROR:" & vbTab & "Version check on the web page returned status " & objHTTP.Status & vbCrLf & vbTab & vbTab & urlCheck
  203. 		Else
  204. 			WScript.Echo "ERROR:" & vbTab & "Version check on the web page returned status " & objHTTP.Status
  205. 		End If
  206. 		Set objHTTP = Nothing
  207. 		Exit Function
  208. 	End If
  209. 	' Return the result
  210. 	GetVersion = strVersion
  211. End Function
  212.  
  213.  
  214. Function ListProgs( myINIFile, myDoDisplay )
  215. 	Dim arrListProgs( ), i
  216. 	Dim objFSO, objFile, objMatches, objMatch, objRE
  217. 	Dim strAllINIText, strProgName
  218. 	Const ForReading = 1
  219. 	ReDim arrListProgs(0)
  220. 	arrListProgs(0) = vbNull
  221. 	Set objFSO  = CreateObject( "Scripting.FileSystemObject" )
  222. 	Set objFile = objFSO.OpenTextFile( myINIFile, ForReading, False )
  223. 	strAllINIText = objFile.ReadAll( )
  224. 	objFile.Close
  225. 	Set objFile = Nothing
  226. 	Set objFSO  = Nothing
  227. 	Set objRE   = New RegExp
  228. 	objRE.Global     = True
  229. 	objRE.IgnoreCase = False
  230. 	objRE.Pattern    = "(?:^|\n|\r)\[([^\n\r\]]+)\](?:\n|\r|$)"
  231. 	Set objMatches = objRE.Execute( strAllINIText )
  232. 	If objMatches.Count = 0 Then
  233. 		WScript.Echo "ERROR:" & vbTab & "No program sections found in INI file."
  234. 		Set objMatches = Nothing
  235. 		Set objRE      = Nothing
  236. 		Exit Function
  237. 	Else
  238. 		If myDoDisplay Then
  239. 			WScript.Echo "Name:" & vbTab & vbTab & "Description:" & vbCrLf _
  240. 			           & "=====" & vbTab & vbTab & "============"
  241. 		End If
  242. 		For Each objMatch In objMatches
  243. 			strProgName = ReadIni( myINIFile, Strip( objMatch.Value ), "ProgName" )
  244. 			If myDoDisplay Then WScript.Echo Strip( objMatch.Value ) & vbTab & vbTab & strProgName
  245. 			If UBound( arrListProgs ) = 0 And arrListProgs(0) = vbNull Then
  246. 				arrListProgs(0) = Strip( objMatch.Value )
  247. 			Else
  248. 				i = UBound( arrListProgs ) + 1
  249. 				ReDim Preserve arrListProgs(i)
  250. 				arrListProgs(i) = Strip( objMatch.Value )
  251. 			End If
  252. 		Next
  253. 	End If
  254. 	ListProgs = arrListProgs
  255. End Function
  256.  
  257.  
  258. Function Max( num1, num2 )
  259. 	If num1 > num2 Then
  260. 		Max = num1
  261. 	Else
  262. 		Max = num2
  263. 	End If
  264. End Function
  265.  
  266.  
  267. Function Min( num1, num2 )
  268. 	If num1 < num2 Then
  269. 		Min = num1
  270. 	Else
  271. 		Min = num2
  272. 	End If
  273. End Function
  274.  
  275.  
  276. Function ReadIni( myINIFile, mySection, myKey )
  277. 	Dim objFSO, objFile, objMatches, objRE
  278. 	Dim strAllINIText, strPattern, strValue
  279. 	Const ForReading = 1
  280. 	ReadIni  = ""
  281. 	strValue = ""
  282. 	Set objFSO  = CreateObject( "Scripting.FileSystemObject" )
  283. 	Set objFile = objFSO.OpenTextFile( myINIFile, ForReading, False )
  284. 	strAllINIText = objFile.ReadAll( )
  285. 	objFile.Close
  286. 	Set objFile = Nothing
  287. 	Set objFSO  = Nothing
  288. 	Set objRE   = New RegExp
  289. 	objRE.Global     = True
  290. 	objRE.IgnoreCase = True
  291. 	objRE.Pattern    = "\[" & mySection & "\]"
  292. 	If objRE.Test( strAllINIText ) Then
  293. 		objRE.Pattern    = "\[" & mySection & "\][\n\r]+(?:[^\n\r=]+=[^\n\r]*[\n\r]+)*?" & myKey & "=([^\n\r]*)(?:\n|\r|$)"
  294. 		Set objMatches = objRE.Execute( strAllINIText )
  295. 		If objMatches.Count > 0 Then
  296. 			strValue = Strip( objMatches.Item(0).SubMatches(0) )
  297. 		End If
  298. 		Set objMatches = Nothing
  299. 		Set objRE      = Nothing
  300. 	Else
  301. 		WScript.Echo "ERROR:" & vbTab & "Program """ & mySection & """ not found in INI file." & vbCrLf _
  302. 		           & vbTab & vbTab & "Use /List switch to list known programs."
  303. 		Set objRE = Nothing
  304. 		Syntax
  305. 	End If
  306. 	ReadIni = strValue
  307. End Function
  308.  
  309.  
  310. Function Strip( myString )
  311. 	Dim strString
  312. 	strString = Trim( myString )
  313. 	Do While Left( strString, 1 ) = " " Or Left( strString, 1 ) = Chr(9) Or Left( strString, 1 ) = """" Or Left( strString, 1 ) = "[" Or Left( strString, 1 ) = vbCr Or Left( strString, 1 ) = vbLf
  314. 		strString = Mid( strString, 2 )
  315. 	Loop
  316. 	Do While Right( strString, 1 ) = " " Or Right( strString, 1 ) = Chr(9) Or Right( strString, 1 ) = """" Or Right( strString, 1 ) = "]" Or Right( strString, 1 ) = vbCr Or Right( strString, 1 ) = vbLf
  317. 		strString = Mid( strString, 1, Len( strString ) - 1 )
  318. 	Loop
  319. 	Strip = strString
  320. End Function
  321.  
  322.  
  323. Sub Syntax
  324. 	Dim strMsg
  325. 	strMsg = vbCrLf _
  326. 	       & "UpdateCheck.vbs,  Version 1.08" _
  327. 	       & vbCrLf _
  328. 	       & "Check if a newer version of the specified program is available" _
  329. 	       & vbCrLf & vbCrLf _
  330. 	       & "Usage:  UpdateCheck.vbs  progname  [ /Verbose ]  [ /NoPopup ]" _
  331. 	       & vbCrLf & vbCrLf _
  332. 	       & "   or:  UpdateCheck.vbs  /All      [ /Verbose ]  [ /NoPopup ]" _
  333. 	       & vbCrLf & vbCrLf _
  334. 	       & "   or:  UpdateCheck.vbs  /List" _
  335. 	       & vbCrLf & vbCrLf _
  336. 	       & "Where:                   progname  is the program to be checked" _
  337. 	       & vbCrLf _
  338. 	       & "                         /Verbose  displays intermediate results too" _
  339. 	       & vbCrLf _
  340. 	       & "                         /All      check all programs found in the INI file" _
  341. 	       & vbCrLf _
  342. 	       & "                         /List     lists all programs found in the INI file" _
  343. 	       & vbCrLf _
  344. 	       & "                         /NoPopup  no popup if an update is available" _
  345. 	       & vbCrLf & vbCrLf _
  346. 	       & "Notes:  This script uses an INI file to specify HOW to check a program's" _
  347. 	       & vbCrLf _
  348. 	       & "        current version and the latest available version on the web." _
  349. 	       & vbCrLf _
  350. 	       & "        You may have to edit the INI file each time the web pages' URL" _
  351. 	       & vbCrLf _
  352. 	       & "        or layout changes." _
  353. 	       & vbCrLf _
  354. 	       & "        Switches may be abbreviated, e.g. /A /NP instead of /All /NoPopup." _
  355. 	       & vbCrLf & vbCrLf _
  356. 	       & "Written by Rob van der Woude" _
  357. 	       & vbCrLf _
  358. 	       & "http://www.robvanderwoude.com"
  359. 	WScript.Echo strMsg
  360. 	WScript.Quit 1
  361. End Sub
  362.  

page last uploaded: 2017-04-06, 13:33