wix toolset - expected values for ManagedRuntimeVersion / ManagedPipelineMode - wix

I am trying to create an MSI using the WiX toolset. I have a couple questions:
In the WebAppPool documentry there are two Properties: ManagedRuntimeVersion and ManagedPipelineMode. What are the expected values for them?
The documentation mentions that they can be set using formatted Property. What are these Properties?
I'll highly appreciate a sample.

ManagedRuntimeVersion refers to the version of .NET the app pool should use (e.g. v4.0)
ManagedPipelineMode refers to the pipeline mode the app pool should run in (e.g. integrated)
Formatted properties just means you can set the values using the name of a Property (wix docs) instead of specifying the value inline

Related

Wix Bundle Upgrade Without Resupplying Password

I have authored an MSI that requires an account and password to be supplied to install and start a Windows Service, so I've added a couple of properties to my 'Product' element for that. I have a requirement that these properties should not need to be resupplied to perform an upgrade and since one of those properties is a password I don't want to persist it's value to the registry (or anywhere). I have achieved this with
<MajorUpgrade ... Schedule="afterInstallExecute" />
Now I'm authoring an exe bootstrapper to bundle this MSI with it's prerequisite, similarly the exe will need to receive values for the properties and pass them to the MSI, so I've added some 'Variable' elements to my bundle and passed them to my 'MsiPackage' element with child 'MsiProperty' elements. And this works great during first install when the values are supplied, but now when I want to upgrade the bundle without supplying values for the properties the bootstrapper passes empty values to the MSI. Something equivalent to...
msiexec /i MyMsi.msi ACCOUNT= PASSWORD=
Which breaks the upgrade. The new version of the Windows Service is attempting to start with an empty value for account and password.
Is there a way to conditionally pass variable values to MSI's as property values?
What happens when both the 'Variable' element attributes 'Hidden' and 'Persisted' are set? Will the password really be hidden?
Is there another pattern I don't know about / haven't thought of?
Something like this doesn't feel like it should require a custom action.
On upgrades you can disable the <InstallServices> standard action.
In one of the products I work with I have the following:
<!-- http://stackoverflow.com/questions/15965539/how-to-only-stop-and-not-uninstall-windows-services-when-major-upgrade-in-wix don't change service config on upgrade -->
<DeleteServices>NOT UPGRADINGPRODUCTCODE</DeleteServices>
<InstallServices>NOT WIX_UPGRADE_DETECTED OR V6INSTALLED</InstallServices>
Because I didn't want to reset the start types of the services is the user has decided to start them manually instead of automatically (it's an option in our product to set this).
By doing this, it should leave the service already installed as is when upgrading instead of trying to re-add it with empty parmeters for the login user/pass
An alternative is to make a salted hash of the password and store the user and salted&hashed password into the registry. On upgrades you can read these values decode the password and use those values.

Managed WiX Bootstrapper packages

I have chained multiple Msi/exec packages in my Bundle.wxs. In my managed Bootstrapper code, I would like to get the parameters (such as DisplayName, Vital, etc) of the current package that is being executed.
Right now, I have only found events that provide the packageID. Can I use this to somehow access other properties of the package?
Yes. A file called BootstrapperApplicationData.xml is created during the build process and included with your Bootstrapper Application. The BootstrapperApplicationData.xml has lots of information about the bundle and packages included in your Bundle Chain, including the DisplayName and sizes and vital.
You'll find the BootstrapperApplicationData.xml right next to your .dll. In managed code you can get it using the following code:
string folder = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
string dataXmlPath = Path.Combine(folder, "BootstrapperApplicationData.xml");
In native code, it is easier to use the helper functions provided in the balutil.lib. Namely BalManifestLoad() then BalInfoParseFromXml() to parse the XML file into a bunch of handy structs. You can see the code in src\ext\BalExtension\balutil\balinfo.cpp.
Finally, the BootstrapperApplicationData.xml can be extended by using CustomTable elements and setting the BootstrapperAppplicationData='yes' attribute.

SharepPoint 2010 Feature Upgrade Action rename field declarative way

I'm looking into Sharepoint 2010 Feature upgrade framework and all over the net I'm seeing examples of how to upgrade a feature by adding a new field to a existing content type and this is done like this:
<UpgradeActions>
<VersionRange BeginVersion="0.0.0.0" EndVersion="0.9.9.9">
<ApplyElementManifests>
<ElementManifest Location="SomeFunctionality_Iteration2\Elements.xml" />
</ApplyElementManifests>
<AddContentTypeField ContentTypeId="0x010073f25e2ac37846bb8e884770fb7307c7"
FieldId="{536DC46C-DC26-4DB0-A97C-7C21E4362A85}" PushDown="TRUE"/>
<AddContentTypeField ContentTypeId="0x010073f25e2ac37846bb8e884770fb7307c7"
FieldId="{4E7A6719-011A-47EA-B983-A4941D688CA6}" PushDown="TRUE"/>
What i don't understand is how would i perform an upgrade to a feature which would rename,*delete* or change any other property a field declaratively from the content type the feature already deployed.
All over the net I'm seeing examples of how to add a Field, but how do i change properties of existing ones using Feature Versioning and Upgrading.
Thanks!
You have to do that using code in the Feature receiver (in Feature_Updating). There's no way to delete or rename a Field using CAML.

How to execute custom action present in MSI without invoking installation?

Given:
Wix 3.0 is used to create MSI.
The product consists of multiple feature.
Each feature has few sub features. It’s a standard MSI feature tree.
Each feature or sub feature depend on multiple external components.
E.g. .NET 4, ASP.NET etc
Custom action written in C# using Wix 3.0 SDK processes these
dependency and evaluates if components are present or not for a
given set of features.
At time of install if dependent component is missing for given
selection of features, installation fails.
To achieve:
Ability to execute prerequisite check, which is already done in MSI as custom action during installation, without installing MSI on a given machine.
Failed Attempts:
1)
Custom action have function signature like this
[CustomAction]
public static ActionResult ProcessFeaturePrerequisite(Session session);
In order to get session object I used following API present in Wix 3.0 SDK
Session session = Installer.OpenPackage("Pathto\\Product.msi", true); // true doesn’t install it. Also tried with false, but didn’t work.
When I invoke the above method with above session following things fail.
session.Features["SomeFeature"].CurrentState;
This throws exception.
System.ArgumentException was unhandled by user code
Message=Feature ID not registered. SomeFeature
Source=Microsoft.Deployment.WindowsInstaller
StackTrace:
at Microsoft.Deployment.WindowsInstaller.FeatureInfo.get_CurrentState()
Also below critical API which determines prerequisite status always returns false.
session.EvaluateCondition(prereq);
2)
I know a command line way to specify features to the above MSI and install it. It goes like this
msiexec /i "Product.msi" ADDLOCAL=ALL REMOVE="Foo,Bar "
I couldn’t find any API in SDK which allows me to pass additional params which returns session object without starting installation. My guess is passing such param will make session.Features more valid.
Questions:
So how do I achieve above goal?
Is there
any API in Wix SDK which allows me to call custom action without
invoking installation?
any way to invoke custom action from command line for a given MSI
without installing?
any way to make Wix to change MSI into accepting a command string
containing custom action name which only evaluates the action?
any better way to do the same?
I suppose you're trying to solve the problem with the wrong tool. As far as I understand, you would like to check the installation prerequisites from inside a certain tool, but not from the installation. As long as the functionality is implemented as a custom action in the MSI package, you'd like to utilize that functionality in order not to duplicate the code.
I would choose a different way in your situation:
Extract the functionality which actually checks for prerequisites into a separate assembly, e.g. checkprereq.dll
Refactor your custom action to reference checkprereq.dll. Note that you'll have to add checkprereq.dll to your Binary table as well as the customaction.dll. You should divide the responsibility here: the custom action part works with MSI stuff - in your case, it's defining which prerequisites to check based on the combination of features a user selected - and the functional part - the actual prerequisites verification, which is done by checkprereq.dll
Use checkprereq.dll separately when you need to check prerequisites not triggering the installation process
The attempts you've outlined here demonstrate an important false assumption: the session object at install time is the same as the installation object you get by just opening the MSI database for read only purpose. IT'S NOT TRUE! Actually, I doubt it makes any sense to reference the session object outside the installation transaction. As its name states, it is an installation session, that is, available in process - not a static thing.
The MSI package should be treated just as a database when it is just a file and not a running installation. Hence, only static information living in MSI package can be queried and used when you just open it for reading and not installing. I mean you can query the Feature table, for instance, but don't expect it to contain information which makes sense in installation time only, like whether a user chose a feature for installation or not.
Hope this makes sense and shows you the right direction.

Wix: Add a sequential registry key

I am writing an installer using Wix 3 which installs a plugin to a 3rd party application. The application uses a group of registry keys to detect installed plugins. Each plugin is required to add a new subkey with a numerical name from 0-9 to the HKEY_LOCAL_MACHINE\SOFTWARE\Vendor\App\Plugins. The key contains a single string value which is the ProgId of a COM component which the application will instantiate. So for example I would need to add the following key to install my plugin:
HKEY_LOCAL_MACHINE\SOFTWARE\Vendor\App\Plugins\0
REG_SZ ProgId "MyCompany.MyPlugin"
However, if the 0 key already exits, my installer needs to be smart enough to create key 1 instead of 0 and on down through key 9. Is there a way to achieve this using the Wix syntax? I know I can write a custom action to do this, but if at all possible I would like to avoid it.
You could use RegistrySearch to find the first empty value. But it would be easier to use the approach I describe at http://www.joyofsetup.com/2007/07/01/semi-custom-actions/.