How to reuse functionality in wix installer - wix

I am new to WIX. I have created an installer to create web site on IIS.I need to use this website installer inside two more wix project. e.g in another project I am creating window service and want create website as well in same project and in another project I want to create database and this website as well.

You can put shared functionality inside a wixlib project.
You basically put shared functionality into <Fragment> tags and use a <ElementRef> tag to include the fragments in your main wix project.
You probably already use the WixUIExtension which looks like it's basically just a wrapper around the ui.wixlib. You incorporate part of the ui wixlib when you do <UIRef Id="WixUI_InstallDir> and then everything in the fragment of WixUI_Installdir.wxs is merged into your main wix project at compile time. (I think the preprocessor does this)
So if you can identify portions of your installer that are shared between your multiple installers, you can make a wix lib that includes multiple InstallComponent.wxs and a way to reference them into your main install. Generally this can be with UIRef, RegistrySearchRef, or in the case where there is no real Ref element you can use, just include a description property at the top of your Fragment something like
<Property Id="ComponentNameInclude" />
then in your installer project you can reference this property to bring in everything in the fragment this property belongs to.
<PropertyRef Id="ComponentNameInclude" />
I would suggest reading through the wix source (I linked the github to one of the files) to get a better idea of how wix itself makes use of some wixlibs.

Related

WiX bootstrapper, global install directory

I have an application with a bootstrapper that installs multiple components below it. The code below uses ninject to have a loosely coupled database layer.
With regards to the bundle/bootstrapper, I would like to move the database layer out into a separate msi in order to support optional data layer choices on install (e.g.: radio buttons to install SQLite/SQLExpress/MySQL etc..).
I am struggling to figure out how to get the install directory working though, as the database components needs to install into the root/install directory of the main application. (rather than using the gac etc).
How can I do this? I have tried the steps mentioned here: How to use properties to set the installation path? but to no avail. I must have something wrong.. but given the code is spread over 5(ish) files, it seems a little large to load here!
Any pointers to get started trying to implement this, or should I go ahead and upload the code?
The method you refer to should work. Note however that the name of the property given in
<MsiProperty Name="INSTALLLOCATION"
should match the name used in wxs file of the corresponding MSI package. Typically if the MSI was created based on WixUI_InstallDir template the name would be APPLICATIONFOLDER and in the default template without the UI it is INSTALLFOLDER.

Putting new dll in exisiting GAC path using wix

I am working on Wix and I have to place a new dll (Let's say New.dll) as a part of MSI installation into a specific path in GAC where some other dll already resides.(Let's say Exisiting.dll. Please note this dll exists before installing my MSI).
So is there a way I can achieve this? Please note New.dll contains native code and is not .net assembly. Thanks.
The GAC is only for files in strongly-named assemblies. An assembly is a versioned set of files, one of which has a manifest. Creating multi-file assemblies is easy but most tools neither help create nor respect that an assembly may have multiple files. The basic tool is the assembly linker. See How to: Build a Multifile Assembly.
A native DLL can be made part part of an assembly with the /linkresource switch for the C# compiler. If you want to fiddle with a C# project file, you can override the standard Compile target and Csc task with your own that will pass linkresources.
WiX does not handle multi-file assemblies. You have to create File elements for each file in the assembly. All such Files should be in the same Component. This is an instance where having a single component makes sense when Organizing Applications into Components.
If want want a different behavior (that is, replace one of the files), then you have to create a new version of the assembly/Component. Hopefully, that is how the previous native DLL got into the GAC in the first place.
I've only done this a little bit years ago. I'm 99% certain that the new.dll would be a companion file of the old.dll. In other words, the old.msi has a component with old.dll as the keyfile. The new.dll has to be added as an additional file to this component so that MsiPublishAssemblies / Fusion API can publish them together into the same storage directly.
You may be able to do this in a new.msi provided that you sync up the component ID (GUID) and mark it as a shared component. You would have to rebuild old.dll with the same strong name (and AssemblyVersion) but with a higher AssemblyFileVersion / Win32 File Version.
MSI component rules require newer DLL's to be backwards compatible. This goes double for the GAC. This seems to be a substantial change to old.dll. It might make sense to just rev the AssemblyVersion and define this as a whole new component and install side by side in the GAC.
The first thing you are going to want to do is search for the file on the system... You can do this with the FileSearch WiX statement:
<Property Id="PROPFILESEARCHEXISTINGDLL" Secure="yes">
<DirectorySearch Id="EXISTINGDLLFOLDERPATH" Path="[WindowsFolder]\assembly\" Depth="5">
<FileSearch Name="Existing.dll"/>
</DirectorySearch>
</Property>
DirectorySearch Reference: http://wixtoolset.org/documentation/manual/v3/xsd/wix/directorysearch.html
FileSearch Reference: http://wixtoolset.org/documentation/manual/v3/xsd/wix/filesearch.html
This will put the full path to the file in the PROPFILESEARCHEXISTINGDLL property. From here you can then reference this property when placing the file on disk. (Assuming of course your have permissions to write to that location...)

How to work with HEAT.exe for dll registry

and i need to register a dll . Right now am registering the dll as below
<CustomAction Id='comReg' Directory='INSTALLLOCATION' Impersonate='no' Execute='deferred'
ExeCommand='"[NETFRAMEWORK40CLIENTINSTALLROOTDIR]regasm.exe" "[INSTALLLOCATION]myProduct.dll" /codebase' Return='check' />
but all are suggesting to use HEAT.exe in internet wherever and whenever i surf . I even have gone through this link. But there they have only the syntax etc. I really dont know how to work with it just by knowing those syntax.
I need some step by step procedure or some good blog which elaborately tell how how to harvest a dll and how to impllement it in to wix code and how the registry will be done , so that i can register my dll based on conditions also.Even i tried this link alse
Regards
Registering a COM component is done through standard Windows Installer actions and tables. Numerous table entries are required so WiX provides heat.exe to harvest COM files. It works by inspecting a file for type libraries and, if the DllRegisterServer entry point is present, running it in a Registry sandbox where changes are intercepted and captured. (In the era of Windows Installer [1999-present], DllRegisterServer is effectively deprecated for any other purpose.)
As you may know, a Feature is the smallest user-selectable unit of installation. A Component is a member of one or Features in one or more Products. Heat creates a component for each file it harvests and a ComponenentGroup for each harvest run. So, you have to pick a ComponentGroup Id and reference it in one or more Features. You also have to pick a Directory Id for the destination of the ComponentGroup.
Now, it is simply a matter of editing your project file to harvest the file. To edit a project file you could use a text editor but Visual Studio is all set up for it. See How to: Edit Project Files.
Add a HarvestFile element to a new or existing ItemGroup, entering the desired ComponentGroup Id and Directory Id
<ItemGroup>
<HarvestFile Include="comserver.dll">
<ComponentGroupName>COM</ComponentGroupName>
<DirectoryRefId>ServerDir</DirectoryRefId>
</HarvestFile>
</ItemGroup>
In your Product.wxs or elsewhere, add a ComponentGroupRef to one or more Features.

How do I build a WixLib without hard-coding the directory reference?

I have an assembly and its dependencies in a folder. I want to create a wixlib (with the binaries baked in) that will contain a ComponentGroup that has all of the files in it. In another wix project, I want to reference that wixlib and say where the files should go (they all should sit next to each other).
Currently, I can use heat.exe to generate a wxs file, which I can run through candle and lit to generate a wixlib. The problem is, heat.exe puts the components into a directory. I can use an XSLT to change the wxs file but I am unable to figure out any way to have the wixlib not have a hardcoded directory reference.
My goal is to make the wixlib not require tribal knowledge in order for someone to use it. They should be able to just reference the wixlib and do something like this in their wxs:
<ComponentGroupRef Id="MyWixLib" Directory="TheirDirectoryRefOfChoice" />
Possibly the best answer is to require tribal knowledge of the directory name but make sure it is unique so the user can alias it as mentioned here: https://stackoverflow.com/a/592177/879046

Adding first custom Dialog Box to WIX in VisualStudio environment

I'm using Visual Studio to build my wix file. So far I have one file Product.wxs and it's working for a simple install.
Now I want to add some custom dialogs. I think from the two articles below, I understand how to do it - after I get my environment set up:
http://blog.torresdal.net/2008/10/24/WiXAndDTFUsingACustomActionToListAvailableWebSitesOnIIS.aspx
and
http://www.merlinia.com/mdt/WiXTutorial2.msl
I downloaded the source, and I see 35 *.wxs file in this directory
wix35-sources.zip\src\ext\UIExtension\wixlib
This is where I'm starting to get lost.
Do I need to copy some (only the ones I want to change) or all these files to my Visual Studio Project. Until now, I have been running with none of these source files.
How does my Product.wxs know to use these files? Does it look at local directory first? Or do I have to rebuild some C# modules?
I included these lines in my Product.wxs, and it gave me the user interface at execution time:
<UIRef Id="WixUI_Mondo" />
<UIRef Id="WixUI_ErrorProgressText" />
Thanks,
Neal
Do I need to copy some (only the ones I want to change) or all these files to
my VisualStudio Project. Until now, I have been running with none of these source files.
Since you are already using WixUI_Mondo, I assume you want to customize that UI. Locate WixUI_Mondo.wxs in the wix sources, and copy that to your visual studio project. Rename the file to WixUI_MyCustomUI.wxs and change the UI Id attribute inside the file to Id="WixUI_MyCustomUI". You don't need to copy any other files yet; the dialogs referenced in the copied UI sequence are compiled into the wix tools as resources, so wix "knows" these dialogs by name.
In your product.wxs file, change the UI reference to <UIRef Id="WixUI_MyCustomUI" />. If you now rebuild your setup, the UI should still look exactly as WixUI_Mondo as we haven't customized anything yet.
If that worked, you'll probably want to customize or add a dialog. Again, you can start from an existing dialog by copying it from the wix sources. You'll also have to edit the WixUI_MyCustomUI.wxs file so that it uses your new dialog. Take a look at this other answer I wrote for an example.
How does my Product.wxs know to use
these files? Does it look at local
directory first? Or do I have to
rebuild some C# modules?
You do not have rebuild any C# modules. The only reason you downloaded the wix sources is because the existing UI sequences and dialogs are good examples to start from. In principle you could also ignore the wix sources and write these wxs files for the UI sequence and dialog definitions from scratch.
When you use the command line tools, you combine multiple wxs files by simply passing multiple file arguments and they will be compiled and linked together. If you use wix with visual studio, you just have to add the wxs file to the project. A non-trivial wix setup will typically be defined by many wxs files.
The content of a wxs file can container references to elements in other wxs files through elements such as UIRef, ComponentRef, ComponentGroupRef, DirectoryRef etcetera.