Extract Source Files from Wise For Windows Installer

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 < 1) Then
    databasePath = InputBox("Please enter the Msi file name including path",,"")
    if databasePath = "" then
        Fail "Cancel Selected"
    end if
    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

' 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
        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
            CopyFile record.StringData(1),TargetDir
        end if

' 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\")
            szOutputLine = szLine
        end if
' 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")
Set DeleteFile = objFS.GetFile("C:\test1.txt")

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,"\")
    iOffset = instr(iCurrentOffset + 1,szPath,"\")
    szPathComponent = mid(szPath,1,iOffset)
    if (not objFS.FolderExists(szPathComponent)) then
    end if
    iCurrentOffset = iOffset
    icount = icount + 1
loop while (iOffset < iLastOffset)
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

This article was originally published on Dec 8, 2000
Page 1 of 1

Thanks for your registration, follow us on our social networks to keep up-to-date