msbuild & wix - multiple installers? - msbuild

I'm working with an application framework that has multiple products. It has a single installer and plugins are included/excluded based on build-server configuration.
I would like to change my build process so that multiple msi files are produced from a single build (one for each product, based on the framework). Is that possible ?

I was strugling the same problem.
I had 2 different builds from 1 wxs file, and for 4 configurations from 1 build. e.g. build=server\client,conf=debug\release,platf=x86\x64.
My issue: to cerate a solution with projects, numbered by the variable of build (in my case there was 2 projects, for server and for client separate). every project needs to be based on one wxs file, and build properties need to be different. I used the standard env variables on Configuration and Platform, and used my own variable Build. I've done in that way. If u need more biulds, create more projects, use more variables...
P.S. If u find the better way, plz contact me.

Related

Increment Version number when checking in to TFS

I have a folder in TFS which has SQL Scripts. At the moment I am manually adding a comment and updating a version number inside the comment every time i make a change and check it back it. This works however was hoping there might be a better way. Is there a way to automate this in TFS?
I have read the following article
Version control project files
do i have to go through such a process for simple .sql files? Are there any other simple ways.
There are a few ways you can do this:
Create an automated build in TFS and write a custom build step / PowerShell script to parse the appropriate SQL scripts, read the version, increment it, and store the new version by either checking in the updated file or a local store
Use a database project (part of SQL Server Data Tools) which will output a DACPAC. Inside the database project, you can set the version as specified here. This stores the version in the project file. If you update your TFS build number to be digits only, you can then update the project file to set that value to match the build using a custom build task. For example, if your build number was yyyy.m.d.R where R is the number of times that build was run today (TFS manages that - it's the revision variable). Or, you could set the the <DacVersion> tag to something like 2.1.0.0 and your build replaces the last digit with yyyymmddr.
I'd recommend using a database project. It's pretty easy to create a new database project off an existing database.
The first way mentioned by Jacob above can achieve that if you just want to incremental the version number of the script/folder, just create a CI build definition.
Actually you can just enable Label sources and set the Label format with predefined environment variables such as $(build.buildNumber), and set without publish any artifacts during build process.
Thus, it will automatically trigger the CI build when you check in files, and the source (SQL Script /folder) will be labeled with the incremental number.
Then you can find the specific versions with the label.

How to permanently save a build variable as a build step?

I have the following variables defined:
Now once a build is complete (the last step in the build process), I want to update the VersionRevision variable, basically increment it.
So I'm looking for an API I can call from C# and create a console application or a powershell script to edit the build definition (if I have to do this)?
You can use VSTS Rest API to update the variable value in Build Definition. Both Console Application and Powershell Script is OK for this.
If I understand correctly, you want to get these build variables and them assignment them as your version number.
After the build completes, update and increment the VersionRevision. It's not a good way and seems not available to achieve it.
In TFS build there is a $(Rev:.r) which means
Use $(Rev:.rr) to ensure that every completed build has a unique name.
When a build is completed, if nothing else in the build number has
changed, the Rev integer value is incremented by one.
Source: Specify general build definition settings
To version your assemblies you could just add an powershell script in your build definition, detail ways to achieve please follow this link from MSDN: Version your assemblies
And usually we only define and assignment variables with the Major and Minor version. If you want to change the value of them. You may need manually edit the build definition.
More related link about how to manage version numbers as part of your vNext builds.
vNext Build Awesomeness – Managing Version Numbers
Generate custom build numbers in TFS Build vNext

How to use CustomAction in WIX Bundle?

To give you a background - I have a 4 MSI's which comes from our vendor and this has to go to our company servers (we are looking at around 3500 servers). As of now, my counterparts are managing this using vbs, ps1 scripts. But the problem with the script is that everytime an update comes we have to worry about uninstalling the existing package before running the new one and a ton of hardcoding.
I want to automate the whole process (with very less hardcoding) by setting up a WIX script to package all the 4 MSI's together. I read about the WIX bundle and used that to create a single MSI. But now there are lot of a variables to be passed to the 4 MSI's, so I thought of using custom actions to set these variables based on the environment/machine where the MSI is running. But I cant make custom action to work? Am i missing something?
A little bit of googling and I saw something like there are no CustomActions in Bundle? can someone confirm?
Also if there are no CA's what are my options? how can I manipulate the variables to be passed on to the 4 MSI's? Most of them needs to be set based on the machine its being run (like install path, user id's, app pool id's etc).
There is a fourth option, a useful lightweight hack, identified by Vijay Kotecha (see http://vijayskotecha.blogspot.com/2013/07/wix-bootstrapper-custom-action.html),...
Essentially, build an <ExePackage> around a pass-through .bat or .cmd batch file. The batch/command file contains the single line '%*' which re-executes all of the command line arguments as a first class command.
Thus:
<ExePackage ... SourceFile="SourcePath\WixCustomAction.cmd"
InstallCommand="my_custom_action.exe my_custom_parameters" />
<ExePackage ... SourceFile="SourcePath\WixCustomAction.cmd"
InstallCommand="my_next_action.exe my_next_parameters" />
Where WixCustomAction.cmd is a file containing only '%*'.
These <ExePackages> can be placed into the <Bundle><Chain> successively as needed using different InstallCommands as needed.
As I see it, you have three options:
Depending on what information you need, you can use the WixUtilExtension to perform simple tasks such as reading registry keys and performing file searches, which you can then pass the results to your installation packages as properties.
Implement custom actions in the individual installation packages themselves (not in the bundle).
Write your own custom bootstrapper application to determine all the properties you need to set, and then pass them to your installation packages. This is more complex than the #1 and #2, but if your interested the following links should get you started:
introducing managed bootstrapper applications and
write a wpf wix installer

TFS 2010: Perform different builds and command line task in sequence?

my build process with TFS 2010 should perform different task one after the other like:
Build 1st project in solution
Execute MSBuild via command line (to publish the project)
Execute a 3rd party tool via command line (to obfuscate the binaries)
Build a 2nd project in the solution (an InstallShield project)
How can I achieve this? I can define several project in the Build Definition but how can I invoke several command line task between these build steps? And the MSBuildArguments in the Build Definition: Are these arguments for every msbuild call for each project/solution?
Thanks
Konrad
At first, you need to add in your build definition the distinct *.*proj instead of one big *.sln - or (even better) construct more than one *.sln & order them to get build in the build definition. So you could organize a Project1.sln, Project2.sln etc that are only used from the Build.
In addition to that, you would have to make changes in the build process template to get this.By default you get something like that, that executes each set project/solution within a bigger foreach:
A good way would be to enhance this as a sequence, where all your custom action are set as InvokeProcess activities:
Obviously, you would have to insert here a flow control, so that Publish & Dotfuscator execute the first time (where Project1.sln gets build), while ISDEV executes the second time (where Project2.sln gets build). In the sample below I used a switch & packed Publish & Dotfuscator in a new Sequence.
Finally, you would have to have a counter of some sort. The most immediate option is to set a new Int32 Variable with default == 1 and increase it by hand during execution. In the sample below this is done in the lower Assign:
This final override of Complie the Project, along with a changed Build Definition should get what you 're after.
The team build definition takes a list of sln's and msbuild project files. You can put simply split your InstallShield project out into it's own solution ( most developers won't have a copy of InstallShield anyways likely ) and write an msbuild targets file for steps 2 and 3. Then just tell your build definition to build solution 1, the targets file and solution 2.
You could also choose to put the stuff in the targets file in a postbuild event for one of the projects in solution 1.
I wouldn't do this in workflow.

WIX multiple copies of same file in msi but only one will be installed

i have multiple environments, build, test, prod etc.
i'd like to create a single installer in wix, which can hold multiple machine.config files. then based on the feature value passed in through the command line only one file will be installed.
conceptualy it sounds easy but i receive an ICE30 error stating that
"ICE30: The target file 'btfrgsa_|[FILENAME]' is installed in '[TARGETDIR]\NETFRAMEWORK40FULLINSTALLROOTDIR64\CONFIG\' by two different components on an LFN system: 'MachineConfigs.WS' and 'MachineConfigs.APP'. This breaks component reference counting.".
what would be the best way to do this?
thanks
Semaj
A couple of approaches:
Create several features and components with files of different names ( 1.config, 2.config ) and then use the CopyFile element to cause x.config to be copied to the real file name. ) This will result in x.config and real.config being deployed but it's harmless and the uninstall will work cleanly.
Identify the differences between the x.configs and use XML changes to apply them at install time using xpath statements.