March 2007 Entries
Build 64-bit MSI file on Cruise Control

There is a known bug when trying to build 64-bit MSI files.  That is, the wrong InstallUtilLib.dll is embedded in the MSI.  A workaround to that problem is to use Orca to manually manipulate the MSI file in embed the correct version - the workaround is documented here.  However, what if you want to automate this process on your build server?  Orca is a windows appication requiring user input. 

To automate this from the command line, you can leverage a few lines of VBScript code that essentially duplicates the Orca functionality.  Specifically, what we are trying to do is embed the 64-bit version of InstallUtilLib.dll into the MSI so that the BadImageFormatException does not rear its ugly head.  The key line of the VBScript is the SetStream method of the Record object.  The complete VBScript solution is shown below and can simply be invoked from CCNet using a standard command line task such as the Exec MSBuild task with the appropriate command line arguments.

Option Explicit
On Error Resume Next

Const msiViewModifyInsert         = 1
Const msiViewModifyUpdate         = 2
Const msiViewModifyAssign         = 3
Const msiViewModifyReplace        = 4
Const msiViewModifyDelete         = 6

If (WScript.Arguments.Count = 0) Then
   Msgbox("No command line argument specified for MSI location. Please try again.")
   Wscript.Quit 1
End If


public sub AdjustInstallUtil()
 On Error Resume Next
 dim msiInstance : msiInstance = WScript.Arguments.Item(0)
 dim installer : Set installer = CreateObject("WindowsInstaller.Installer")
 dim installerDb : Set installerDb = installer.OpenDatabase(cstr(msiInstance), 1)
 dim sqlCommand : sqlCommand = "SELECT * FROM Binary WHERE `Name`='InstallUtil'"
 dim view : Set view = installerDb.OpenView(sqlCommand)

 dim record : Set record = view.Fetch()

 If Not record Is Nothing Then
  const dataCol = 2
  record.SetStream dataCol, "C:\Program Files\CruiseControl.NET\64BitMSI\InstallUtilLib.dll"
  view.Modify msiViewModifyUpdate, record
 End IF
 'clean up
 Set installerDb = Nothing
 Set view = Nothing
 Set installer = Nothing
 'Error Handling
 If Err.number > 0 Then
   Msgbox("Error while adjusting x64 InstallUtilLib: " & Err.Description & ": " & Err.Source & ": " & Err.number)
 End If
end sub

Posted On Saturday, March 17, 2007 8:44 PM | Comments (2)

View Steve Michelotti's profile on LinkedIn

profile for Steve Michelotti at Stack Overflow, Q&A for professional and enthusiast programmers

Google My Blog

Tag Cloud