Description:
This script will change GUIDs to upper case, as per Windows Installer Best Practises
Usage
CScript.exe {Script} {MSI}
Script
'set up log file
Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
Const ForReading = 1
Const ForWriting = 2
Const ForAppending = 8
'create a name/path for log file
Dim MSIPath : Set MSIPath = fso.GetFile(WScript.Arguments(0))
Dim logFile : logFile = Left(MSIPath.Path, InStrRev(MSIPath.Path, ".") - 1) & ".log"
Dim objLogFile : Set objLogFile = fso.OpenTextFile(logFile, ForAppending, True)
WriteLog "Make GUIDs upper Case"
WriteLog "Processing: " & MSIPath.Name
'create 2 constants - one for when we want to just query the MSI (read) and one for when we want to make changes (write)
Const msiOpenDatabaseModeReadOnly = 0
Const msiOpenDatabaseModeTransact = 1
Const msiViewModifyReplace = 4
'create WindowsInstaller.Installer object
Dim oInstaller : Set oInstaller = CreateObject("WindowsInstaller.Installer") 'open the MSI (the first argument supplied to the vbscript)
Dim oDatabase : Set oDatabase = oInstaller.OpenDatabase(WScript.Arguments(0),msiOpenDatabaseModeTransact)
'do regex stuff'
Dim re : Set re = new regexp 'Create the RegExp object
Dim Match
'pattern for guid
re.Pattern = "(\{{1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{1})"
re.IgnoreCase = true
re.Global = True
Dim guid : guid = ""
Dim valueView, valueRecord
Dim columnValue : columnValue = ""
Dim tableValue : tableValue = ""
Dim sql : sql = "SELECT `Table`,`Column` FROM `_Validation` WHERE `Category` = 'Guid'"
Dim columnView : Set columnView = oDatabase.OpenView(sql)
'execute the query
columnView.Execute 'fetch the first row of data (if there is one!)
Dim columnRecord : Set columnRecord = columnView.Fetch
'whilst we've returned a row and therefore columnRecord is not Nothing
While Not columnRecord Is Nothing
columnValue = columnRecord.StringData(2)
tableValue = columnRecord.StringData(1)
If oDatabase.TablePersistent(tableValue) = 1 Then
Set valueView = oDatabase.OpenView("SELECT `" & columnValue & "` FROM `" & tableValue & "`")
'execute the query
valueView.Execute 'fetch the first row of data (if there is one!)
Set valueRecord = valueView.Fetch
'whilst we've returned a row and therefore valueRecord is not Nothing
While Not valueRecord Is Nothing
guid = valueRecord.StringData(1)
If guid <> UCase(guid) Then
valueRecord.StringData(1) = UCase(guid)
valueView.Modify msiViewModifyReplace, valueRecord
WriteLog "Modifying Table: " & tableValue & ", column: " & columnValue & " and changing GUID from: " & guid & " to " & UCase(guid)
End If
Set valueRecord = valueView.Fetch
Wend
Set valueRecord = Nothing
End If
Set columnRecord = columnView.Fetch
Wend
Set columnRecord = Nothing
Dim originalRegKey : originalRegKey = ""
Dim regkey : regkey = ""
Dim originalRegValue : originalRegValue = ""
Dim regValue : regValue = ""
Dim registryView, registryRecord
Dim Matches
Set registryView = oDatabase.OpenView("SELECT `Registry`, `Key`,`Value` FROM `Registry`")
registryView.Execute
Set registryRecord = registryView.Fetch
While Not registryRecord Is Nothing
originalRegKey = registryRecord.StringData(2)
regkey = originalRegKey
'change guids in key column to upper case
Set Matches = re.Execute(regkey)
If Matches.Count > 0 Then
For Each Match in Matches
regkey = replace(regkey,Match.value,UCase(Match.value),1,-1,1)
Next
If StrComp(originalRegKey,regkey,0) <> 0 Then
registryRecord.StringData(2) = regkey
registryView.Modify msiViewModifyReplace, registryRecord
WriteLog "Modifying Registry Key: " & originalRegKey & " and changing To " & regkey
End If
End If
Set Matches = Nothing
originalRegValue = registryRecord.StringData(3)
regValue = originalRegValue
'change guids in value column to upper case
Set Matches = re.Execute(regValue)
If Matches.Count > 0 Then
For Each Match in Matches
regValue = replace(regValue,Match.value,UCase(Match.value),1,-1,1)
Next
If StrComp(originalRegValue,regValue,0) <> 0 Then
registryRecord.StringData(3) = regValue
registryView.Modify msiViewModifyReplace, registryRecord
WriteLog "Modifying Registry Value: " & originalRegValue & " and changing To " & regValue
End If
End If
Set Matches = Nothing
Set registryRecord = registryView.Fetch
Wend
Set registryRecord= Nothing
Set registryView= Nothing
oDatabase.commit
objLogFile.Close
Set fso = Nothing
Set objLogFile = Nothing
Set re = Nothing
Set oDatabase = Nothing
Set oInstaller = Nothing
Sub WriteLog(LogMessage)
WScript.echo Now() & ": " & LogMessage
objLogFile.Writeline(Now() & ": " & LogMessage)
End Sub