Kae Travis

Rename Single-file Components

Description

This script will rename single-file components to their filename.

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 "Renaming Single-file Components to their File Name"
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) 
Dim filenameLength : filenameLength = 0
Dim component : component = ""
Dim filename : filename = ""
Dim tempTable : tempTable = ""	
Dim tempColumn : tempColumn = ""
Dim tempColVal : tempColVal = ""
Dim componentView, componentRec, fileView, fileRec, id, compExistView, compExistRec, tablesRec, tablesView, tempTableRec, tempTableView
If oDatabase.TablePersistent("Component") = 1 AND oDatabase.TablePersistent("File") = 1 And oDatabase.TablePersistent("FeatureComponents") Then
Set componentView = oDatabase.OpenView("SELECT `Component` FROM `Component`")
componentView.Execute
Set componentRec = componentView.Fetch
'component table has records
Do Until componentRec Is Nothing
component = componentRec.StringData(1)
If Not isMSMData(component) Then
Set fileView = oDatabase.OpenView("SELECT `FileName` FROM `File` WHERE `Component_`='" & component & "'")
fileView.Execute
If not fileView.Fetch is nothing and fileView.Fetch is nothing Then  'it has one file
Set fileRec = fileView.Fetch
filename = fileRec.StringData(1)
If InStr(filename,"|") Then
'attempt to get actual filename if there is a sfn equivalent
filename = Split(filename,"|")(1)
End If
filenameLength = Len(filename)
If Not (LCase(filename) = Left(LCase(component),filenameLength)) Then	
If Not IsNumeric(Left(filename,1)) AND Not Instr(filename,"-") > 0 Then						
'if filename doesnt start with a number or contain a '-' we rename
'(otherwise if it does contain one of these it will constantly rename the ocmponent each time you run it)
renameComponent component,filename
End If 
End If					
End If
Set fileView = Nothing
Set fileRec = Nothing
end If
Set componentRec = componentView.Fetch
Loop
Set componentRec= Nothing
Set componentView= Nothing
End If
oDatabase.Commit	
objLogFile.Close
Set fso = Nothing
Set objLogFile = Nothing
Set oDatabase = Nothing
Set oInstaller = Nothing
Sub WriteLog(LogMessage)
WScript.echo Now() & ": " & LogMessage
objLogFile.Writeline(Now() & ": " & LogMessage)
End Sub
'returns true if tempData contains MSM decoration
Function isMSMData(tempData)
isMSMData = False
Dim Match
Dim regEx : Set regEx = New RegExp
regEx.MultiLine = vbTrue
regEx.global = vbTrue
regEx.Pattern = "[A-Za-z0-9]{8}_[A-Za-z0-9]{4}_[A-Za-z0-9]{4}_[A-Za-z0-9]{4}_[A-Za-z0-9]{12}"
For Each Match in regEx.Execute(tempData)
isMSMData = True
Next
Set regEx = Nothing
End Function
Function renameComponent(oldComponent,newComponent)
'check component doesnt exist
id = 0		
Do While componentExists(newComponent)	
id = id + 1			
newComponent = newComponent & id
Loop
Set tablesView = oDatabase.OpenView("SELECT `Table`,`Name` FROM `_Columns` WHERE `Name`= 'Component_' OR Name`= 'Component'") 
tablesView.Execute
Set tablesRec = tablesView.Fetch
Do While Not tablesRec Is Nothing
tempTable = tablesRec.StringData(1)
tempColumn = tablesRec.StringData(2)
If oDatabase.TablePersistent(tempTable) = 1 Then 					
Set tempTableView = oDatabase.OpenView("SELECT `" & tempColumn & "` FROM `" & tempTable & "` WHERE `" & tempColumn & "`='" & oldComponent & "'")
tempTableView.Execute
Set tempTableRec = tempTableView.Fetch	
Do Until tempTableRec Is Nothing						
tempTableRec.StringData(1) = newComponent
tempTableView.Modify msiViewModifyReplace, tempTableRec
Set tempTableRec = tempTableView.Fetch
Loop
Set tempTableView = Nothing
Set tempTableRec = Nothing							
End If			
Set tablesRec = tablesView.Fetch
Loop						
Set tablesView = Nothing
Set tablesRec = Nothing
Set tablesView = oDatabase.OpenView("SELECT `Table`,`Column` FROM `_Validation` WHERE `Category`= 'Condition' OR `Category`= 'Formatted' OR `Category`= 'Identifier'") 
tablesView.Execute
Set tablesRec = tablesView.Fetch
Do While Not tablesRec Is Nothing
tempTable = tablesRec.StringData(1)
tempColumn = tablesRec.StringData(2)
If oDatabase.TablePersistent(tempTable) = 1 Then 					
Set tempTableView = oDatabase.OpenView("SELECT `" & tempColumn & "` FROM `" & tempTable & "`")
tempTableView.Execute
Set tempTableRec = tempTableView.Fetch	
Do Until tempTableRec Is Nothing	
tempColVal = tempTableRec.StringData(1)
If InStr(tempColVal,"$" & oldComponent) Then
tempTableRec.StringData(1) = Replace(tempColVal,"$" & oldComponent,"$" & newComponent)
tempTableView.Modify msiViewModifyReplace, tempTableRec						
End If
If InStr(tempColVal,"?" & oldComponent) Then
tempTableRec.StringData(1) = Replace(tempColVal,"?" & oldComponent,"?" & newComponent)
tempTableView.Modify msiViewModifyReplace, tempTableRec						
End If
Set tempTableRec = tempTableView.Fetch
Loop
Set tempTableView = Nothing
Set tempTableRec = Nothing							
End If			
Set tablesRec = tablesView.Fetch
Loop						
Set tablesView = Nothing
Set tablesRec = Nothing
WriteLog "Component: " & oldComponent & " renamed to : " & newComponent
End Function
'used to see if a component exists or Not
Function componentExists(component)
'this function is called initially with '1' as the id.  Then this value gets incrememnetd if the component exists
Set compExistView = oDatabase.OpenView("SELECT `Component` FROM `Component` WHERE `Component`='" & component & "'")
compExistView.Execute
Set compExistRec = compExistView.Fetch
If Not compExistRec is Nothing Then
Set compExistView = Nothing
Set compExistRec = Nothing
componentExists = True			
Else
Set compExistView = Nothing
Set compExistRec = Nothing
componentExists = False
End If	
End Function

 

Rename Single-file Components
Rename Single-file Components

Leave a Reply