by John Loomes
This script addresses a bug in WISE for Windows Installer 3 where if a registry entry in an MSI package has a value that contains square brackets e.g. [value], then WISE
will interpret everything in between the brackets as an MSI property and attempt to resolve it via the Property table. This results in incorrect registry values begin written when the package is
installed. In order to make WISE interpret square brackets literally, it is necessary to use the following syntax:
[[ ][]].
This script addresses a bug in WISE for Windows Installer 3 where if a registry entry in an MSI package has a value that contains square brackets e.g. [value], then WISE
will interpret everything in between the brackets as an MSI property and attempt to resolve it via the Property table.
This script walks through the
Regsitry table in an MSI package, and fixes values in square
brackets as it comes across them. It writes the changes it makes to
an Excel spreadsheet to enable you to check for errors.
N.B. This bug is fixed in the next
release of WISE for Windows Installer (apparently)…
‘ This utility analyses Wise
for windows installer packages,
‘ checks for Registry keys which
contain square brackets ([ ]) which
‘ are to be ignored in by the
installer and converts them to [[ ] and []]
‘ This is done by
checking against the Property table
‘
Option
Explicit
Dim databasePath, szTableName, objFS
Const
msiOpenDatabaseModeReadOnly = 0
Const msiOpenDatabaseModeTransact
= 1
set objFS = CreateObject( “Scripting.FileSystemObject”
)
Dim argNum, argCount:argCount =
Wscript.Arguments.Count
If (argCount databasePath = InputBox(“Please enter the
Msi file name including
path”,,”C:testingMYMSI.msi”)
if databasePath
= “” then
Fail “Cancel
Selected”
end if
else
databasePath = Wscript.Arguments(0)
End
If
‘ Enter the Table name to
update
szTableName = InputBox(“Please enter the Table name to
check”,,”Registry”)
if szTableName = “”
then
Fail “Cancel Selected”
end
if
if (not objFS.FileExists(databasePath)) then Fail “File
does not exist”
‘ Dump Changes to an excel spreadsheet so it
can be analysed
dim objXL, intIndex: intIndex = 2
set objXL =
CreateObject( “Excel.Application” )
objXL.Visible =
TRUE
objXL.WorkBooks.Add
objXL.Cells(1, 1).Value =
“Replacement String”
objXL.Rows(1).Font.Bold = True
‘
Export the Registry Table
TableImpExp szTableName,
“Export”
‘ Process it to change source
Const ForReading =
1, ForWriting = 2, ForAppending = 8
Dim InpFile, OutpFile,
objRegExp, szLine, szOutputLine, DeleteFile
Set objRegExp = new RegExp
objRegExp.pattern =
“[*]”
objRegExp.ignorecase =
TRUE
Set InpFile =
objFS.OpenTextFile(“C:test.txt” , ForReading)
Set OutpFile = objFS.OpenTextFile(“C:test1.txt” , ForWriting,
True)
While(InpFile.AtEndOfStream
True)
szLine =
InpFile.readline
if
(objRegExp.Test(szLine))
then
szOutputLine =
FixLine(szLine)
else
szOutputLine = szLine
end if
OutpFile.WriteLine(szOutputLine)
Wend
InpFile.close
OutpFile.close
‘ Import the Registry Table
TableImpExp
szTableName, “Import”
‘Delete the temporary files
created
Set DeleteFile =
objFS.GetFile(“C:test.txt”)
DeleteFile.Delete
Set DeleteFile
= objFS.GetFile(“C:test1.txt”)
DeleteFile.Delete
wscript.Echo “Operation Complete”
Wscript.Quit
0
‘This function parses a line looking for [] combinations
and checks property and fixes
Function FixLine(szLine)
dim
iLSquareOff,iLSquareCurr,iRSquareOff,iRSquareCurr,szLReplace,
szRReplace
dim szLLeave, szRLeave, szProperty,
szMatchFound
iLSquareCurr=1:iRSquareCurr=1
szLReplace=”[[]”:szRReplace=”[]]”
szLLeave=”[“:szRLeave=”]”
FixLine
= “”
do
iLSquareOff =
instr(iLSquareCurr,szLine,”[“) + 1
iRSquareOff
= instr(iRSquareCurr,szLine,”]”)
if
iRSquareOff=0 then
Fixline = FixLine &
mid(szLine,iRSquareCurr)
exit do
end if
Fixline =
FixLine & mid(szLine,iRSquareCurr,(ILSquareOff – IRSquareCurr
-1))
‘ Need to put a fix in here for cases like
[]] or [[ ] etc
szProperty =
mid(szLine,iLSquareOff,(IRSquareOff –
ILSquareOff))
szMatchFound =
msiPropertyExists(szProperty)
if (szMatchFound
= “”) then
FixLine =
FixLine & szLReplace & szProperty &
szRReplace
objXL.Cells(intIndex, 1).Value =
szLReplace & szProperty & szRReplace
intIndex = intIndex + 1
else
FixLine = FixLine
& szLLeave & szProperty & szRLeave
end if
iRSquareOff = iRSquareOff +
1
ILSquareCurr =
ILSquareOff
IRSquareCurr =
IRSquareOff
loop
end function
‘ This function checks
the property table in the MSI database for szProperty
Function
msiPropertyExists(szProperty)
‘ Process SQL statements
Dim
query, view, record, message, szFirstChar
msiPropertyExists=”TRUE”
szFirstChar =
mid(szProperty,1,1)
‘ Check for special
characters in the first position
if
szFirstChar = “!” then Exit Function
if
szFirstChar = “$” then Exit Function
if
szFirstChar = “~” then Exit Function
if
szFirstChar = “#” then Exit Function
if
szFirstChar = “” then Exit Function
if
szProperty = “SHELLNOOP” then Exit Function
msiPropertyExists=”” ‘ Set to false after passing the tests
above
‘ Connect to Windows installer object
Dim openMode :
openMode = msiOpenDatabaseModeTransact
On Error Resume
Next
Dim installer : Set installer = Nothing
Set installer =
Wscript.CreateObject(“WindowsInstaller.Installer”) :
CheckError
‘ Open database
Dim database : Set database =
installer.OpenDatabase(databasePath, openMode) :
CheckError
query = “Select Property FROM
Property WHERE Property='” & szProperty &
“‘”
Set view = database.OpenView(query) :
CheckError
view.Execute :
CheckError
Set record =
view.Fetch
‘ Big kludge here but should work.
When found record is defined otherwise use “”
msiPropertyExists=record.StringData(1)
If openMode = msiOpenDatabaseModeTransact
Then database.Commit
end function
sub
TableImpExp(szTable, ImpExp)
‘ Connect to Windows installer
object
Dim openMode : openMode =
msiOpenDatabaseModeTransact
On Error Resume Next
Dim installer
: Set installer = Nothing
Set installer =
Wscript.CreateObject(“WindowsInstaller.Installer”) :
CheckError
‘ Open database
Dim database : Set database =
installer.OpenDatabase(databasePath, openMode) :
CheckError
if ImpExp = “Import” then
‘ Import the updated
table into the database
database.import “C:”, “test1.txt”
end
if
if ImpExp = “Export” then
‘ Export the table to a
file
database.export szTable , “C:”, “test.txt”
end
if
If openMode = msiOpenDatabaseModeTransact Then
database.Commit
end Sub
Sub
CheckError
Dim message,
errRec
If Err = 0 Then Exit
Sub
message = Err.Source & ” ” &
Hex(Err) & “: ” & Err.Description
If
Not installer Is Nothing
Then
Set errRec =
installer.LastErrorRecord
If Not errRec Is Nothing Then message = message & vbLf &
errRec.FormatText
End If
Fail message
End Sub
Sub
Fail(message)
Wscript.Echo
message
Wscript.Quit 2
End
Sub