Page 1 of 3 123 LastLast
Results 1 to 5 of 12

Thread: Replace a single file embedded in an MSI

  1. #1
    Join Date
    Jul 2008
    Posts
    29

    Replace a single file embedded in an MSI

    First off, I would like to say I am no installer guy. Only now am I learning a little about MSIs, tables etc.. so please bear with me if I sound too newbish.

    I am faced with a situation like this:
    There is an xml file that is to be installed by one of the products am working on. This XML file is not fixed in the sense that, it has to be generated fresh for each customer. As such, I already have the ability to use InstallShield standalone component and crank out a new installer using the new xml file each time. However, this would need me to maintain all the input files, merge modules , prqs needed by the installer ( times the no. of version ofs the product ). I would like to simplify this so that the installer would be generated with a dummy xml file during build time, but then on demand, this installer will be massaged and injected with the new xml file.

    With that background, I did some research on various tools and this is what I got done so far:
    • Managed to use msidb to extract the data1.cab using:
      msidb.exe" -d test.msi -x Data1.cab
    • Managed to use cabarc to extract the data1.cab contents on to a local folder using:
      cabarc X Data1.cab *.* c:\tmp\files\
    • Managed to replace the xml file in the files folder
    • Managed to repack the cab file using:
      cabarc N Data1.cab c:\tmp\files\*.*
    • Managed to inject it back into the msi using:
      rem remove stream first
      msidb.exe" -d test.msi -k Data1.cab
      rem now add it
      msidb.exe" -d test.msi -a Data1.cab


    I see that the msi is created and when I use orca to open it, I see the media table having the #data1.cab entry. However, when I run the msi, it comes up with an error that a file is not found and aborts installation.

    I have seen quite a few posts with a similar situation, but haven't really seen a solution that works. Some recommend using transforms, some recommend pulling that xml file out of the CAb and use from elsewhere, so it could be updated without repacking the CAb etc..

    Any help would be appreciated. Am willing to try what I can. Have most of the tools like CAB SDK, Installer SDK, Wi*.vbs files, orca.

  2. #2
    MichaelU's Avatar
    MichaelU is offline InstallShield Software Engineer
    Join Date
    Jan 2004
    Location
    Schaumburg, IL
    Posts
    4,392
    This approach is going to be full of difficult steps like you've seen. The failure is probably due to the order or keys of the files in the CAB changing, as MSI cares about this. I'd suggest one of two things. If the XML file is similar enough in all scenarios that it only needs a small piece of it updated (say an attribute's value), it may be worth exploring using the XML Changes view to update a base file to have what you need by updating properties, or even transforming the XML changes with a transform.

    If the differences aren't so simple and you truly do need a separate file, perhaps you could add your dummy file as a Support File, then restream the updated one into its entry in the ISSetupFile table as your only post-build step. You'd have to update any logic in your installer to actually copy it into place (and remove it at uninstall) if you go with this route, but it'll make the post-build part much more approachable.

    As an aside, when you're making these surgical updates post-build, don't forget to take care to update the Package Code (of the summary information stream), and possibly the ProductCode and/or UpgradeCode properties as appropriate.
    Michael Urman - Staff Software Engineer - Flexera Software: InstallShield Team

  3. #3
    Join Date
    Jul 2008
    Posts
    29
    ok. I figured how to do this:

    Here is what I am doing in case it helps someone:
    It's a batch file using the baseline from here.

    Code:
    @ECHO OFF
    @ECHO.
    @ECHO Updating MSI file with new files
    @ECHO.
    
    @ECHO Remove target output file
    rmdir /S /Q dump
    
    @ECHO unzip MSI
    msiexec /a Input.msi TARGETDIR="c:\tmp\TestPackaging\dump" /quiet
    
    @ECHO press any key when installation is done
    rem pause
    
    @ECHO replace xml file
    copy .\some.xml ".\dump\CommonAppData\{Company Name}\{Product Name}\some.xml"
    
    @ECHO Update MSI information from source tree
    CScript //nologo WiFilVer.vbs .\dump\Input.msi
    CScript //nologo WiFilVer.vbs .\dump\Input.msi /U
    
    @ECHO Copy original file to new output file
    COPY /Y ".\dump\Input.msi" ".\dump\Output.msi"
    
    REM @ECHO Create a single cabinet file with all your files
    REM CScript //nologo WiMakCab.vbs ".\dump\Output.msi" Data1 /C
    
    @ECHO Create and embed the file cabinet
    CScript //nologo WiMakCab.vbs ".\dump\Output.msi" Data1 /C /U /E /S
    
    DEL /Q "Data1.CAB"
    DEL /Q "Data1.INF"
    DEL /Q "Data1.RPT"
    DEL /Q "Data1.DDF"
    
    @ECHO Done
    PAUSE
    This works fine. Question I have is with the first step i.e. admin install using msiexec /a.

    Is this adminstrative install gauranteed to install all the files ? Reason being, there some optional command lines I can use to enable/disable certain features. Is it safe to use the msiexec /a ?

  4. #4
    Join Date
    Jul 2008
    Posts
    29
    MichaelU, thanks so much for the reply.

    I figured how to do this, although I have a question towards the end. Also not sure if your concerns are still valid with the approach I have listed below ( especially the product code , package and upgrade codes ). Would appreciate your insight into this.

    Here is what I am doing in case it helps someone:
    It's a batch file using the baseline from here.

    Code:
    @ECHO OFF
    @ECHO.
    @ECHO Updating MSI file with new files
    @ECHO.
    
    @ECHO Remove target output file
    rmdir /S /Q dump
    
    @ECHO unzip MSI
    msiexec /a Input.msi TARGETDIR="c:\tmp\TestPackaging\dump" /quiet
    
    @ECHO press any key when installation is done
    rem pause
    
    @ECHO replace xml file
    copy .\some.xml ".\dump\CommonAppData\{Company Name}\{Product Name}\some.xml"
    
    @ECHO Update MSI information from source tree
    CScript //nologo WiFilVer.vbs .\dump\Input.msi
    CScript //nologo WiFilVer.vbs .\dump\Input.msi /U
    
    @ECHO Copy original file to new output file
    COPY /Y ".\dump\Input.msi" ".\dump\Output.msi"
    
    REM @ECHO Create a single cabinet file with all your files
    REM CScript //nologo WiMakCab.vbs ".\dump\Output.msi" Data1 /C
    
    @ECHO Create and embed the file cabinet
    CScript //nologo WiMakCab.vbs ".\dump\Output.msi" Data1 /C /U /E /S
    
    DEL /Q "Data1.CAB"
    DEL /Q "Data1.INF"
    DEL /Q "Data1.RPT"
    DEL /Q "Data1.DDF"
    
    @ECHO Done
    PAUSE
    This works fine. Question I have is with the first step i.e. admin install using msiexec /a.

    Is this adminstrative install gauranteed to install all the files ? Reason being, there some optional command lines I can use to enable/disable certain features. Is it safe to use the msiexec /a ?

  5. #5
    Join Date
    Jul 2008
    Posts
    29
    ok. I figured how to do this, although I have a question towards the end

    Here is what I am doing in case it helps someone:
    It's a batch file using the baseline from here.

    Code:
    @ECHO OFF
    @ECHO.
    @ECHO Updating MSI file with new files
    @ECHO.
    
    @ECHO Remove target output file
    rmdir /S /Q dump
    
    @ECHO unzip MSI
    msiexec /a Input.msi TARGETDIR="c:\tmp\TestPackaging\dump" /quiet
    
    @ECHO press any key when installation is done
    rem pause
    
    @ECHO replace xml file
    copy .\some.xml ".\dump\CommonAppData\{Company Name}\{Product Name}\some.xml"
    
    @ECHO Update MSI information from source tree
    CScript //nologo WiFilVer.vbs .\dump\Input.msi
    CScript //nologo WiFilVer.vbs .\dump\Input.msi /U
    
    @ECHO Copy original file to new output file
    COPY /Y ".\dump\Input.msi" ".\dump\Output.msi"
    
    REM @ECHO Create a single cabinet file with all your files
    REM CScript //nologo WiMakCab.vbs ".\dump\Output.msi" Data1 /C
    
    @ECHO Create and embed the file cabinet
    CScript //nologo WiMakCab.vbs ".\dump\Output.msi" Data1 /C /U /E /S
    
    DEL /Q "Data1.CAB"
    DEL /Q "Data1.INF"
    DEL /Q "Data1.RPT"
    DEL /Q "Data1.DDF"
    
    @ECHO Done
    PAUSE
    This works fine. Question I have is with the first step i.e. admin install using msiexec /a.

    Is this adminstrative install gauranteed to install all the files ? Reason being, there some optional command lines I can use to enable/disable certain features. Is it safe to use the msiexec /a ?

Page 1 of 3 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •