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.
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.")
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
Set installerDb = Nothing
Set view = Nothing
Set installer = Nothing
If Err.number > 0 Then
Msgbox("Error while adjusting x64 InstallUtilLib: " & Err.Description & ": " & Err.Source & ": " & Err.number)