How to call a MSI file from another MSI? - installation

I am using WIX for my application's setup project, I have to install device drivers along with my application setup. so I have two driver installer files for each x86 and x64 platforms (since I have to use difxapp_x64/difxapp_86 reference file I need to have two separate installation projects), and one application setup project. now based on the platform I want to call either one of the driver installer msi file and the application installer file from one Msi file ( Bootstrapper !?). How can I accomplish this ?
after a bit of search i come to know in wix 3.6 there is a new tool know as 'Burn', this will help me to call collection of installation packages that are chained together.. so I have created a new setup project as Bootstrapper. but when I build its creating the msi file successfully but could not able to run it.. here is the code:
<?xml version="1.0" encoding="UTF-8"?>
<?define version="1.3.0.3"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Bundle Name="Bootstrap" Version="1.0.0.0" Manufacturer="Bootstrap" UpgradeCode="58A81C66-C066-4CA1-9712-D884C11C88BD">
<BootstrapperApplicationRef Id="WixStandardBootstrapperApplication.RtfLicense" />
<Chain>
<ExePackage Id="ExeProject"
SourceFile="../../../CCSetupProject/bin/Release/CCSetupProject.exe"
InstallCommand="/q /ACTION=Install"
Name="iCConnectInstaller"
Vital="yes"
PerMachine="yes"/>
</Chain>
</Bundle>
</Wix>
when I click the Bootstrapper.msi file it says "Preparing to install" and then "This installation package could not be opened. Contact the application vendor to verify that this is a valid Windows Installer package."
dont know what I am missing here!, anybody got this error before ?

You can't by having two separate packages.
To solve the problem you have to build a merge module for the drivers, and then merge it with the main installation.
By having a separate merge module, you can create an additional package which install only the drivers, or you can use product features to select what is gettin installed.

Related

How to manage Windows firewall ports while running an MSI installation?

I have MSI Windows Installer files created by using the Wix Toolset and Wix files (*wxs). My requirement is that I need to open or close specific firewall ports while running the MSI installation.
Is there a way that it can be managed through specifications in the Wix files (*wxs) used to make the MSI installer?
There is an extension called FirewallException in WiX. You need to reference it inside your Visual Studio project. Find it at: C:\Program Files (x86)\WiX Toolset v3.11\bin\WixFirewallExtension.dll for a standard installation of WiX.
As to the usage of the actual element:
You can find sample markup on github.com.
Bob Arnson's blog:
http://www.joyofsetup.com/2008/05/17/new-wix-feature-firewall-extension/
Basic usage step-by-step:
In Visual Studio project, add reference to C:\Program Files (x86)\WiX Toolset v3.11\bin\WixFirewallExtension.dll
Right click your WiX project
Click "Add => Reference..." & browse to above path and double click file
Add to top level Wix element in your Project.wxs source file: xmlns:fire="http://schemas.microsoft.com/wix/FirewallExtension"
Then add the markup. Something along these lines:
<Component Feature="ProductFeature">
<File Source="$(env.SystemRoot)\myexecutable.exe">
<fire:FirewallException Id="FWX1" Name="Service" Port="[PORT]" Protocol="tcp" Scope="any" />
</File>
</Component>

How to read content of text file in Wix Toolset Bootstrapper

I am using the WiX toolset to build an installer, I want to read the version from a text file. The text file is located in mybootstrapper like below:
below is the code where i want to read the content of text file
<Bundle IconSourceFile='product.ico'
Name="Retail Grip"
Version="Version.txt" <!-- i know this is not correct -->
Manufacturer="Company Name"
UpgradeCode="PUT-GUID-HERE">
Oh, it is a WiX bundle - and that's "Wax"? I hear it is a WiX tool of sorts? I am not sure exactly how it works (screenshot down the page in that link). Maybe there are restrictions on the use of compiler variables when using it?
I wrote the below before I saw that Wax file and I thought you had a normal WiX source and not a bundle source. Either way, let me add what I wrote and see if it helps. Similarities.
Also: Neil Sleightholm's WiX Burn Template (towards top). Give that link a spin first please.
In a regular WiX file you could use a pre-processor variable: $(var.CurrentVersion) (compiler variable). Something like this:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define UpgradeCode="PUT-GUID-HERE"?>
<?define CurrentVersion="1.0.0.0"?>
<Product Id="*" Name="Sample" Language="1033" Version="$(var.CurrentVersion)"
Manufacturer="Someone" UpgradeCode="$(var.UpgradeCode)">
<...>
You can put the variables in its own "include file": Variables.wxi.
<Include>
<?define UpgradeCode="PUT-GUID-HERE"?>
<?define CurrentVersion="1.0.0.0"?>
</Include>
Larger sample here for this approach (do have a quick skim of this one).
And then include the file in your main WiX source:
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include Variables.wxi ?>
<Product Id="*" Name="Sample" Language="1033" Version="$(var.CurrentVersion)"
Manufacturer="Someone" UpgradeCode="$(var.UpgradeCode)">
<...>
There are also localization variables: WiX (Windows Installer Xml), Create universal variables - link time variable resolution (light.exe), as opposed to the compile time resolution of pre-processor variables (candle.exe). Some context.
Some Relevant Links:
Localization Variables in use: Wix toolset license agreement multi-languages issue
How to make Win64 attribute as a variable in wixlib?
https://helgeklein.com/blog/2014/09/real-world-example-wix-msi-application-installer/
With WiX Include files, you can keep simple values separate from the bulk of the WiX markup. With WiX preprocessing, you can define named substitution values used in attributes or text nodes or conditional compilation, and then refer to them as $(var.name).
-- Version.wxi --
<?xml version="1.0" encoding="utf-8"?>
<Include>
<?define Version="1.2.3" ?>
</Include>
-- Bundle.wxs --
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?include "Version.wxi" ?>
<Bundle
Version="$(var.Version)"
…
It is sometimes convenient to generate include files in a source project in anticipation of them being used downstream, or generate them as the first steps of a WiX project.
I see you are using Visual Studio for your WiX Bootstrapper project. A Visual Studio project is a specialized MSBuild project (as are most types of Visual Studio projects). That means you can put general MSBuild things into the project file. You can open the .wixproj file as an XML file in an XML editor (such as Visual Studio).
MSBuild allows you define new tasks either from an external DLL or inline, using a .NET language. In this case, a few lines of C# will do fine to define the task. Then you would invoke it before the main build tasks. Like many build systems that use MSBuild, WiX ensures the target BeforeBuild is executed before it gets to work. So, you just have to define BeforeBuild.
The task is named CreateVersionWxi.
<UsingTask
TaskName="CreateVersionWxi"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v12.0.dll">
<ParameterGroup />
<Task>
<Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Using Namespace="System.Xml.Linq" />
<Code Type="Fragment" Language="cs"><![CDATA[
var version = File.ReadAllText("version.txt");
var wxi =
new XDocument(
new XComment("*** GENERATED FILE. DO NOT EDIT ***"),
new XElement("Include",
new XProcessingInstruction("define", "Version='" + version + "'")));
wxi.Save("version.wxi");
]]></Code>
</Task>
</UsingTask>
<Target Name="BeforeBuild">
<CreateVersionWxi />
</Target>
Finally, if you add version.txt to your project with its Build Action, say, as Content, the project will be seen as needing to be rebuilt whenever version.txt changes. That will help if you have the WiX project open in Visual Studio while you are externally changing version.txt.
You don't need to add Version.wxi to your project but doing so increases its visibility to future maintainers.
Tip: Some Visual Studio users are more familiar with the Build Events on the project pages. To clue them in, you could enter this as a pre-build event command line: REM See the BeforeBuild target in the .wixproj file

Failed Deployment for Plugins in MS CRM 2013 with ILMerge

I developed a single plugin for on-premise crm 2013 (PreCreateOpportunityProduct - nothing special). In my visual studio crm solution I added a project (called BusinessLogic) that includes my generated Entities.cs as well as partial classes for each entity. Therefore I can encapsulate the logic for one special entitiy in one separate class. No big deal so far.
Now I want to use those logic, therefore I add the project reference in my plugin project. I know that I need to merge all needed DLL's to one, so I added a post-build event to merge all dll's with ILMerge.
Overview of Solution / Project with used DLLs:
The post-build command looks as follows:
mkdir "$(TargetDir)Merged"
"$(SolutionDir)Libs/ilmerge.exe" /keyfile:"$(ProjectDir)keypair.snk" /target:library /copyattrs /targetplatform:v4,"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0" /out:"$(TargetDir)Merged\Flag.Plugins.dll" "$(TargetDir)Flag.Plugins.dll" "$(TargetDir)BusinessLogic.dll" "$(TargetDir)Microsoft.Crm.Sdk.Proxy.dll" "$(TargetDir)Microsoft.Xrm.Sdk.dll"
del "$(TargetDir)*.*" /Q
move "$(TargetDir)Merged\*.*" "$(TargetDir)"
The RegisterFile.crmregister:
<?xml version="1.0" encoding="utf-8"?>
<Register xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://schemas.microsoft.com/crm/2011/tools/pluginregistration">
<Solutions>
<Solution Assembly="Flag.Plugins.dll" Id="f4dff197-5b7a-e411-80c3-005056ba5a51" IsolationMode="None" SourceType="Database">
<PluginTypes>
<Plugin Description="Plug-in to PreOpportunityProductCreate" FriendlyName="PreOpportunityProductCreate" Name="Flag.Plugins.PreOpportunityProductCreate" Id="0f7bd0bc-2b7b-e411-80c3-005056ba5a51" TypeName="Flag.Plugins.PreOpportunityProductCreate">
<Steps>
<clear />
<Step CustomConfiguration="" Name="PreOpportunityProductCreate" Description="Pre-Operation of Opportunity Product Create" Id="107bd0bc-2b7b-e411-80c3-005056ba5a51" MessageName="Create" Mode="Synchronous" PrimaryEntityName="opportunityproduct" Rank="1" SecureConfiguration="" Stage="PreInsideTransaction" SupportedDeployment="ServerOnly">
<Images />
</Step>
</Steps>
</Plugin>
</PluginTypes>
</Solution>
</Solutions>
<XamlWorkflows />
</Register>
Note: I am Deployment Manager + System administrator -> all permissions
When I click Deploy on CrmPackage project, the error
Error registering plugins and/or workflows. Plug-in assembly does not contain the required types or assembly content cannot be updated. C:\Program Files (x86)\MSBuild\Microsoft\CRM\Microsoft.CrmDeveloperTools.CrmClient.targets
Note 2: When I deploy the plugin.dll without merging all the other DLLs the deployment works like charm, but the plugin throw the exception because the BusinessLogic.dll is not known.
Can anyone help me with this issue?
Thanks in advance
I found the problem: I was merging too many files! In detail: It was the Microsoft.Crm.Sdk.Proxy.dll and Microsoft.Xrm.Sdk.dll. Those libs are already in the crm server GAC. After removing those files from my ilmerge command, the deployment finally works.
Here is the link which gave me the important hints:
https://community.dynamics.com/crm/f/117/p/146347/326928.aspx#326928

Custom nuget feed, VS doesn't see package as installed

Hi all
I have a local Nuget source with a package containing some default items I want in my projects (default corporate models and styles and some default pages). It is only copying items in to the project and adding a connection string to the web.config, nothing fancy.
I can install the package via the Package Manager Console and the GUI. However, it never shows as installed. This means that I cannot update it nor can I uninstall it. If I go to the GUI, it shows the package as not installed, even though it has added all items to the project and has a folder for the package in the packages directory.
Also, I want to use this NuGet package to overwrite some files that already exist in the default MVC project (such as AccountController and LogonUserControl.ascx). Can this be done or will I need to start off with the blank MVC template instead of the default?
Packages.config:
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="MyCompanyMVC" version="1.1" />
</packages>
NuGet won't overwrite files - I don't believe there's a way to force it, however you could probably "work around" this by using a PowerShell script (tools/install.ps1) to delete the old file and rename your injected file to have the required name.

Bootstrapper: How to compile the application and prerequisite in single .msi package?

I am creating an .msi package for the application which has a prerequisite for installation.
I am using the Visual Studio 2005 Bootstrapper for this task.
To this end, I did the following:
Located the folder C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\BootStrapper\Packages\ and created a folder for my prerequisite (made it same structure as 'dotnetfx'); created the 'product.xml' and 'package.xml' and placed them appropriately. I kept the xml files very simple so far to test the installation:
product.xml
<?xml version="1.0" encoding="utf-8"?>
<Product ProductCode="MyPrereq" xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper">
<PackageFiles CopyAllPackageFiles="false">
<PackageFile Name="MyPrereq.exe" />
</PackageFiles>
<InstallChecks>
</InstallChecks>
<Commands Reboot="None">
<Command PackageFile="MyPrereq.exe" EstimatedInstallSeconds="90">
<InstallConditions>
</InstallConditions>
<ExitCodes>
<ExitCode Value="0" Result="Success"/>
<DefaultExitCode Result="Fail" String="GeneralFailure" FormatMessageFromSystem="true" />
</ExitCodes>
</Command>
</Commands>
</Product>
package.xml
<?xml version="1.0" encoding="utf-8"?>
<Package Name="MyPrereq" Culture="Culture" xmlns="http://schemas.microsoft.com/developer/2004/01/bootstrapper">
<Strings>
<String Name="Culture">en</String>
<String Name="DisplayName">MyPrereq</String>
<String Name="GeneralFailure">A fatal error occurred. The installation failed.</String>
</Strings>
</Package>
Now I can add the prerequisite from the list and build my setup project.
The problem:
The build output is the 'setup.exe', the 'MyApp.msi' package, plus the subfolder called 'MyPrereq' which contains 'MyPrereq.exe'.
I would like the build to create a 'setup.exe' and a single 'MyApp.msi', which would contain the 'MyPrereq' inside, with no additional files/directories.
I know that the .NET framework is another prereq for my app, and it is included in the same .msi, so that should be possible somehow.
How can I achieve this?
You can create a self-extracting installer with tools such as IExpress (coming with Windows) containing all files in a single executable (see this SO posting).
You cannot have an MSI file installing its own pre-requisites. First, because Windows Installer itself is a pre-requisite (and must be installed by a non MSI exe) and second because Windows Installer installations are transactional and don't support the chained execution of MSI files. This basically means that one MSI installation cannot start another MSI installation. As a consequence, any pre-requisites must be installed by a separate bootstrapper (by the way, the installation is no longer transactional - the pre-requisites won't get uninstalled if your MSI installation fails).
There seems to be a basic mis-understanding about the bootstrapper mechanism though. The bootstrapper can currently only be generated by Visual Studio or MSBuild. Afaik it is not possible with WiX. Look for the GenerateBootstrapper task in MSBuild (see this SO posting).
I managed to do that with IExpress.
Had to use a small trick, however, which is described here
Creating a bootstrapper for a VS Shell application
Unfortunately, the MSBuild task
doesn't provide the option to have the
configuration resource use
prerequisite installers found in the
target directory, so you must manually
update the appropriate resource file
to remove the hard-coded path that
looks for prerequisites in a
sub-directory of the same name.
Open the Setup.exe program in Visual
Studio's resource editor
Double-click
the resource named, SETUPCFG in the 41
folder
Search for the "Vs Shell\"
string and delete the two occurrences
that appear
Save the resource file
and the Setup.exe executable will be
updated automatically
Run iexpress
Create a new package by following the
IExpress wizard's steps and make sure
to include the following files: The
MyVSShellApplication.msi file The
Setup.exe bootstrapper file The
vs_shell_isolated.enu.exe file
The problem was that bootstrapper puts the prerequisites into a subfolder, and IExpress does not recognise subfolders. Have to be careful while editing 'setup.exe' too, didn't get it correct on the first try.

Resources