Иногда приходится довольно часто и тщательно проверять установку продукта. Чтобы это не занимало много времени, желательно эту процедуру автоматизировать. Сразу оговорюсь, я расскажу, как можно проверить, что все файлы и ключи реестра находятся на своих местах (а не непосредство сам мастер установки). Собственно, весь интрумент будет состоять из двух частей:
- исходных данных (xml-документ с описанием устанавливаемых файлов и ключей реестра)
- скрипта проверки установки.
Т.е. на входе скрипта – xml-документ, на выходе – вывод в консоль результатов проверки.
Почему был выбран формат xml. Во-первых, потому-то с ним достаточно удобно работать в vbscript. Во-вторых, с xml будет проще расширить функциональность скрипта (например, хранить кроме пути к файлу еще и его версию/хеш, и/или другие данные или настройки).
Собственно, xml-документ может быть такого формата:
<?xml version="1.0"?>
<installation-test>
<file>путь и имя файла</file>
<regentry>Имя ключа реестра\параметр</regentry>
</installation-test>
Пример файла:
<?xml version="1.0"?>
<installation-test>
<file>%SystemRoot%\system32\msxml.dll</file>
<file>%SystemRoot%\system32\msxmlr.dll</file>
<file>%SystemRoot%\system32\msvcp71.dll</file>
<file>%SystemRoot%\system32\msvcr71.dll</file>
<file>%ProgramFiles%\My Company\My Product\file.dll</file>
<regentry>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultUserName</regentry>
<regentry>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\DefaultDomainName</regentry>
<regentry>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Version</regentry>
<regentry>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectX</regentry>
<regentry>HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MessengerService</regentry>
<regentry>HKEY_LOCAL_MACHINE\SOFTWARE\My Company\My Product\KeyName</regentry>
</installation-test>
Скрипт будет поддерживать переменные окружения в путях к файлам (%SystemRoot%, %ProgramFiles% и др.). В теге <regentry> можно указывать как разделы реестра, так и отдельные параметры. Алгоритм работы скрипта очень простой:
- Прочитать из xml список файлов.
- Пройти по списку файлов, проверить, существует ли указанный файл и вывести результат проверки.
- Прочитать из xml список параметров ключей реестра.
- Проверить существует ли такой параметр реестра. Если да, то вывести результат.
- Если нет, проверить существует ли такой раздел реестра и вывести результат.
Собственно, вот сам этот скрипт:
Option Explicit
Const strXMLSource = ".\input.xml"
Const strOk = "[Ok]"
Const strFail = "[Fail]"
main
Sub main
Dim xmlDocument, xmlFile, xmlFilesList, xmlRegEntry, xmlRegEntries, xmlNewFile
Dim wshShell, str, i
Set wshShell = CreateObject("WScript.Shell")
Set xmlDocument = CreateObject("Msxml2.DOMDocument")
xmlDocument.async = False
If (xmlDocument.Load(strXMLSource) = 0) Then
WScript.Echo "Fail open xml-file"
WScript.Quit (255)
End If
xmlDocument.setProperty "SelectionLanguage", "XPath"
Set xmlFilesList = xmlDocument.selectNodes ("//*/file")
For Each xmlFile In xmlFilesList
str = wshShell.ExpandEnvironmentStrings (xmlFile.text)
If IsFileExists (str) Then
PrintResult str, strOk
Else
PrintResult str, strFail
End If
Next
Set xmlRegEntries = xmlDocument.selectNodes ("//*/regentry")
For Each xmlRegEntry In xmlRegEntries
str = wshShell.ExpandEnvironmentStrings (xmlRegEntry.text)
If IsRegEntryExists (str) Then
PrintResult str, strOk
ElseIf IsRegKeyExists (str) Then
PrintResult str, strOk
Else
PrintResult str, strFail
End If
Next
End Sub
Function IsFileExists (fullFilename)
Dim fso
Set fso = WScript.CreateObject("Scripting.FileSystemObject")
If fso.FileExists (fullFilename) Then
IsFileExists = True
Else
IsFileExists = False
End If
End Function
Function IsRegEntryExists (strRegEntry)
Dim WshShell, str
On Error Resume Next
Set WshShell = WScript.CreateObject("WScript.Shell")
str = WshShell.RegRead(strRegEntry)
If Err.Number = 0 Then
IsRegEntryExists = True
Else
IsRegEntryExists = False
End If
On Error Goto 0
End Function
Function IsRegKeyExists (strFullRegKey)
Dim dictRegPartitions
Dim strComputer, objRegistry
Dim RegPartition, strParentKeyName, strNames, strTargetKeyName
Dim vDividedFullRegKey, strKey, i
Set dictRegPartitions = CreateObject ("Scripting.Dictionary")
dictRegPartitions.Add "HKEY_CLASSES_ROOT", &H80000000
dictRegPartitions.Add "HKEY_CURRENT_USER", &H80000001
dictRegPartitions.Add "HKEY_LOCAL_MACHINE", &H80000002
dictRegPartitions.Add "HKCU", &H80000001
dictRegPartitions.Add "HKLM", &H80000002
vDividedFullRegKey = Split (strFullRegKey, "\")
RegPartition = dictRegPartitions.Item (vDividedFullRegKey(0))
strTargetKeyName = vDividedFullRegKey(UBound(vDividedFullRegKey))
strParentKeyName = Left(strFullRegKey, Len(strFullRegKey) - Len(strTargetKeyName))
strParentKeyName = Right(strParentKeyName, Len(strParentKeyName) - Len(vDividedFullRegKey(0)) - 1)
strComputer = "."
Set objRegistry = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & _
strComputer & "\root\default:StdRegProv")
objRegistry.EnumKey RegPartition, strParentKeyName, strNames
IsRegKeyExists = False
On Error Resume Next
For Each strKey In strNames
If StrComp(strTargetKeyName, strKey, 1) = 0 Then
IsRegKeyExists = True
Exit For
End If
Next
On Error Goto 0
End Function
Sub PrintResult(strItem, strResult)
Dim nDotCount
nDotCount = 80 - Len(strItem) - Len(strREsult)
If nDotCount < 0 Then nDotCount= nDotCount + 80
WScript.Echo strItem & String(nDotCount, ".") & strResult
End Sub
Для работы скрипта xml-файл должен находить в том же каталоге, что и скрипт. Чтобы изменить местоположение xml, нужно поменять константу strXMLSource.
Для удобства запуска скрипта можно создать batch-файл такого содержания:
@cscript //NoLogo test.vbs
@pause
Его можо будет запускать из проводника. Для xml из примера вывод будет такой (в консольном окне):
C:\windows\system32\msxml.dll...............................................[Ok] C:\windows\system32\msxmlr.dll..............................................[Ok] C:\windows\system32\msvcp71.dll.............................................[Ok] C:\windows\system32\msvcr71.dll.............................................[Ok] C:\Program Files\My Company\My Product\file.dll...........................[Fail] HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Default UserName....................................................................[Ok] HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\Default DomainName..................................................................[Ok] HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Internet Explorer\Version.............[Ok] HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DirectX...............................[Ok] HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MessengerService......................[Ok] HKEY_LOCAL_MACHINE\SOFTWARE\My Company\My Product\KeyName.................[Fail] Для продолжения нажмите любую клавишу . . .
В дальнейшем можно добавить вывод результатов в файл (например, в html с таблицей). А пока можно перенаправить вывод скрипта в файл таким образом:
cscript.exe //NoLogo имя_скрипта > output.txt


Суббота, Январь 31, 2009 в 22:47
[...] корректности установки продукта с помощью утилиты, проверяющей наличие необходимых файлов и ключей [...]