This website uses cookies. By clicking Accept, you consent to the use of cookies. Click Here to learn more about how we use cookies.
Turn on suggestions
Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.
- Revenera Community
- :
- InstallShield
- :
- InstallShield Forum
- :
- Replace a single file embedded in an MSI
Subscribe
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Subscribe
- Mute
- Printer Friendly Page
‎Aug 06, 2008
11:29 AM
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:
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.
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.
(11) Replies
‎Aug 06, 2008
01:32 PM
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.
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.
‎Aug 06, 2008
01:35 PM
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.
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 ?
Here is what I am doing in case it helps someone:
It's a batch file using the baseline from here.
@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 ?
‎Aug 06, 2008
01:54 PM
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.
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 ?
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.
@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 ?
‎Aug 06, 2008
05:04 PM
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.
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 ?
Here is what I am doing in case it helps someone:
It's a batch file using the baseline from here.
@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 ?
‎Aug 07, 2008
10:16 AM
Administrative installs should create a full image of the contents of the MSI; feature filtering happens when that image is run to install it on a target machine. As for the package and product code question, it's a rule that can be broken, but only carefully, when you know 100% that the slightly different packages will never be installed on the same computer, and probably other caveats I'm not thinking of right now. So don't do it lightly. Take a look at the windows installer help topics on this, including Package Codes.
‎Aug 07, 2008
11:44 AM
Thanks for the heads up. Appreciate it. I will look into the link you pointed out. Skimming through it, it seems that what I am doing is messy.
I am starting to like the idea of using an mst. Some questions I have:
1. Can the mst file generation ( which references the new xml file ) be automated/scripted ? i.e. I need to crank this all up without using an IDE.
2. Also, I would like to have a single installer EXE. Can the mst file be embedded into the EXE ? Again, if yes, can this step of embedding the mst into the EXE be automated/scripted ( using IsCmdBld / vbscripting or other utils ? )
I am starting to like the idea of using an mst. Some questions I have:
1. Can the mst file generation ( which references the new xml file ) be automated/scripted ? i.e. I need to crank this all up without using an IDE.
2. Also, I would like to have a single installer EXE. Can the mst file be embedded into the EXE ? Again, if yes, can this step of embedding the mst into the EXE be automated/scripted ( using IsCmdBld / vbscripting or other utils ? )
‎Aug 07, 2008
02:30 PM
It's certainly possible to script the creation of transforms. For the complexity you're likely to be dealing with, it may be reasonable to use Windows Installer automation, but it should also be possible to use InstallShield's automation layer. I don't think it would be feasible to do it with command lines alone.
As for packing it back up in a single EXE, we don't offer any way to do this after the build (except pure InstallScript projects with the ReleasePackager exe), sorry.
As for packing it back up in a single EXE, we don't offer any way to do this after the build (except pure InstallScript projects with the ReleasePackager exe), sorry.
‎Aug 07, 2008
02:46 PM
MichaelU wrote:
As for packing it back up in a single EXE, we don't offer any way to do this after the build (except pure InstallScript projects with the ReleasePackager exe), sorry.
Thanks for the reply ! I need to have an EXE installer since I have PRQ dependencies. So ,that practically kills all possibilities of being able to do this even if I could get the xml into the MSI using a transform or otherwise 😞
Thanks again for your help. I bumped into another thread where a similar scenario was presented where the OP had all the files needed for bundling but that last step wasn't possible since there wasn't a tool that could do this. Is this something that is planned for a future release ?
‎Aug 10, 2008
10:43 PM
I have been thinking about the XML Changes view. I have managed to manipulate the XML file contents with a value of a property. Now, all I have to do is change the property value. I again managed to change the property at runtime by configuring the CmdLine key in the setup.exe setup.ini section ( using the IDE ).
I could now theoretically do the same using setupini.exe isn't it ? Is there a setupini.exe for IS 2009 ? I tried the one for IS 10.5 and although it said it successfully modified the setup.exe, the setup.exe now fails to run ( "error reading setup initialization file" generated when I run the exe ). Any clues ?
I could now theoretically do the same using setupini.exe isn't it ? Is there a setupini.exe for IS 2009 ? I tried the one for IS 10.5 and although it said it successfully modified the setup.exe, the setup.exe now fails to run ( "error reading setup initialization file" generated when I run the exe ). Any clues ?
‎Aug 11, 2008
05:09 PM
Just a quick update on this. I got this thing to work using a internal_setupini.exe available in the Attachments section ( the link in the downloads section is broken ).
http://kb.acresso.com/selfservice/microsites/search.do?cmd=displayKC&docType=kc&externalId=Q107253
http://kb.acresso.com/selfservice/microsites/search.do?cmd=displayKC&docType=kc&externalId=Q107253
‎Aug 14, 2008
12:24 PM
This issue is resolved. Just so someone in future might need something like this, here is what I did:
Goal: Each installation needed to have a just a different values in a predefined XML file that is installed. So, was looking for a way to do this post installer generation rather than having to build the installer all the way each time.
solution:Gist was to use XML File changes view to modify the installed XML using user-defined property values. The property values would in turn be set by a custom action which would be written to read from a user-defined section in the setup.ini file embedded in the setup.exe. The user defined section in the setup.ini would be inserted by the setupini.exe tool.
These are the steps to update a key value of say customdata in an XML file called , say CustomData.xml:
Hope this helps someone.. Thanks to MichaelU for all the tips provided.
Goal: Each installation needed to have a just a different values in a predefined XML file that is installed. So, was looking for a way to do this post installer generation rather than having to build the installer all the way each time.
solution:Gist was to use XML File changes view to modify the installed XML using user-defined property values. The property values would in turn be set by a custom action which would be written to read from a user-defined section in the setup.ini file embedded in the setup.exe. The user defined section in the setup.ini would be inserted by the setupini.exe tool.
These are the steps to update a key value of say customdata in an XML file called , say CustomData.xml:
- Let us assume the CustomData.xml is already added to the file and folders view.
- Go to Property Manager and add a new property called, say, CUSTOMDATA
- Go to XML File Changes view and on the RHS, right click and select import and point to the CustomData.xml. This should generate the XML file structure.
- Here in , select the file name and on the general tab , make sure the XML file destination is set right.
- Next, select the node whose data you want modify at installation time. Go to the Advanced tab in the RHS and int the Content edit field, enter [CUSTOMDATA] ( the square brackets indicating it is a property ). Save project.
- Go to InstallScript section and if there is not a file, add add new script file from right mouse menu and add a function like below:
#include "ifx.h"
export prototype UpdateCustomData(HMSI);
#define INI_NAME "setup.ini"
// The section, key, and value to update the file.
#define SECTION_NAME "CustomDataSection"
#define KEY_NAME "CustomData"
#define KEY_PROPERTY_NAME "CUSTOMDATA"
function UpdateCustomData(hMSI)
// To Do: Declare local variables.
NUMBER nResult, nvResult1,nvResult2;
STRING svMatchingFileName,svResult1,svResult2,svFileName,svPath;
STRING svValue;
begin
nResult = FindAllFiles (FOLDER_TEMP, "*.MSI", svMatchingFileName, RESET);
while(nResult = 0)
//extract file name
ParsePath ( svFileName, svMatchingFileName,FILENAME);
ParsePath ( svPath, svMatchingFileName,PATH);
if(GetFileInfo(svMatchingFileName,FILE_SIZE,nvResult1,svResult1) = 0) then
if(GetFileInfo(SRCDIR ^ svFileName,FILE_SIZE,nvResult2,svResult2) = 0) then
//compare
if(StrCompare(svResult1,svResult2) = 0 ) then
// To Do: Write script that will be executed when UpdateRegistrationInformation is called.
if (GetProfString (svPath ^ INI_NAME, SECTION_NAME, KEY_NAME, svValue) == 0) then
// Display the key and its current value.
MsiSetProperty(hMSI,KEY_PROPERTY_NAME,svValue);
endif;
nResult = -1;
endif;
endif;
endif;
if(nResult = 0) then
nResult = FindAllFiles (FOLDER_TEMP, "*.MSI", svMatchingFileName, CONTINUE);
endif;
endwhile;
end;
What this does is, it finds the setup.ini file and reads the section in it , gets the value and updates the MSI's property. - Now, go to custom actions and sequences view, right clikck on Custom Actions on the RHS, select New Install Script and enter a name. In the common tab on the RHS, select the UpdateCustomData from the dropdown. Select an appropriate sequence ( for e.g. Install UI Sequence set to After SetupInitialization ).
- Those steps above should create an installer that is capable of reading from ini file and updating the xml file during installation.
- The last step that needs to be done after the setup.exe is ready is massaging the custom data in the setup.exe which can be done through command line as:
SetupIni.exe setup.exe CustomDataSection CustomData "my own custom data"
Hope this helps someone.. Thanks to MichaelU for all the tips provided.