by John Loomes
This script is specifically for those
using Wise for Windows Installer to create MSI Packages. It extracts
the source files from the package, and places the, in the correct
hierarchy under a root directory called ‘Source’, it then modifies
the source path within the MSI file such that the MSI Package will
use the extracted files as the SOURCE files at next compile. This
serves two purposes: i) you can analyse the source files, ii) You
can make changes to the source files and recompile the package
without having to install the application on your
machine.
This script is specifically for those
using Wise for Windows Installer to create MSI Packages.
‘ This utility analyses Wise for
windows installer packages,
‘ copies the files from the “c:”
directory to the “.source” directory
‘ where the msi file
exists. It produces an excel spreadsheet of non “C:” items
‘
which are usually components.
Option Explicit
Dim
databasePath, TargetDir, 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”,,””)
if
databasePath = “” then
Fail “Cancel Selected”
end
if
else
databasePath =
Wscript.Arguments(0)
End If
if (not
objFS.FileExists(databasePath)) then Fail “File does not
exist”
TargetDir = mid(databasePath,1,instrrev(DatabasePath,””))
& “Source”
‘wscript.Echo TargetDir
‘ Dump interesting
stuff to an excel spreadsheet
‘dim objXL, iNonCDrive: iNonCDrive
= 2
‘set objXL = CreateObject( “Excel.Application”
)
‘objXL.Visible = TRUE
‘objXL.WorkBooks.Add
‘ 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
‘
Process SQL statements
Dim query, view, record, message,
rowData
query = “Select SourcePath from
WiseSourcePath”
Set view =
database.OpenView(query) : CheckError
view.Execute : CheckError
Do
Set record =
view.Fetch
If record
Is Nothing Then Exit
Do
rowData =
Empty
if
(Ucase(mid(record.StringData(1),1,3)) “C:”)
then
‘
If it’s not an item on the “C:” drive then display it in a
spreadsheet
‘
objXL.Cells(iNonCDrive, 1).Value =
record.StringData(1)
‘
iNonCDrive = iNonCDrive +
1
else
CopyFile
record.StringData(1),TargetDir
end if
Loop
‘ Export the sourcepath
table to a file
database.export “WiseSourcePath”, “C:”,
“test.txt”
‘ 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 =
“C:”
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 =
objRegExp.Replace(szLine,”.source”)
else
szOutputLine = szLine
end if
OutpFile.WriteLine(szOutputLine)
Wend
InpFile.close
OutpFile.close
‘ Reimport the updated sourcepath table into the
database
database.import “C:”, “test1.txt”
If openMode =
msiOpenDatabaseModeTransact Then database.Commit
‘Delete the
temporary files created
Set DeleteFile =
objFS.GetFile(“C:test.txt”)
DeleteFile.Delete
Set DeleteFile
= objFS.GetFile(“C:test1.txt”)
DeleteFile.Delete
MsgBox(“Operation Complete”)
Wscript.Quit
0
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
Sub
CreatePath(szPath)
‘ This routine parses through a given path and
creates it if it does not exist
dim iOffset,iCurrentOffset,
iLastOffset, szPathComponent, icount
icount = 1
iCurrentOffset
= 1: iOffset = 1
iLastOffset =
instrrev(szPath,””)
do
iOffset =
instr(iCurrentOffset + 1,szPath,””)
szPathComponent = mid(szPath,1,iOffset)
if
(not objFS.FolderExists(szPathComponent))
then
objFS.CreateFolder(SzPathComponent)
end if
iCurrentOffset =
iOffset
icount = icount + 1
loop while
(iOffset end sub
sub CopyFile( szSource,
szTarget)
dim szDriveRemoved,szTargetFile
‘ Remove the drive
info when creating the path
szDriveRemoved =
mid(szSource,4)
szTargetFile = szTarget &
szDriveRemoved
CreatePath szTargetFile
if
(objFS.FileExists(szSource)) then
objFS.CopyFile szSource,szTargetFile
end if
end
sub