How can I maintain file reference integrity from a WIX Setup Library - wix

I am using the Wix Toolset 3.8 Visual Studio add-in. I have created a WIX Setup Library which encapsulates some common components that will be consumed by various service deployment projects. This library includes references to several solution files which need to be packaged into each deployment.
These dependencies are used in my wix library fragments in a few different ways. For example:
<Binary Id="InstallationScript" SourceFile=".\Dependency1.vbs" />
<CustomAction Id="DependencyAction"
BinaryKey="InstallationScript"
VBScriptCall=""
Execute="deferred"
Return="check"
HideTarget="no"/>
<Component Id="DLL_Component" Guid="4745D9E2-0EBA-EE57-D8DB-677ADA9E9EC8">
<File Id="DLL1" Name="Dependency1.DLL" Source=".\Dependency1.dll" Vital="yes" KeyPath="yes" DiskId="1"/>
</Component>
The WIX Setup Library builds fine whether I add the files to the project as a link or copy them into the project directory, and whether I reference them in the project directory or use a relative path to their original location. The problem comes when I include the fragment in my WIX Setup Project for my service deployment.
<Custom Action="DependencyAction" Before="InstallFinalize">
NOT INSTALLED AND NOT UPGRADINGPRODUCTCODE
</Custom>
The Setup Project is not at the same relative depth in the folder structure, so a relative path does not point to the same place as it does when referenced from the WIX Library. When I reference the action or feature from the WIX library I get errors like The system cannot fine the file '.\Dependency1.dll' The XML is being read exactly as it is and referenced from the Setup Project location rather than from the Library Project location, so the relative directory is wrong. I can set the relative path in the WIX library to what it should be for the Setup Project that consumes it, or I can copy the solution files into the Setup Project directory as well, but of course, that completely defeats the purpose of using a common WIX library. There are other service deployment projects that need to consume this library.
So the question is, how do I reference solution files in a WIX library in a way that can be used by the Setup Project that consumes it, regardless of the directory that the Setup Project is in?

Create a binary .wixlib that contains the files referenced in your authoring. (That's -bf at the command line, BindFiles property in the .wixproj, "Bind files into the library file" checkbox in Votive.)

Related

How do I stop removal of files during uninstallation using Wix

When uninstalling my application, I'd like to configure the Wix setup to NOT to remove few files that were added as part of the installation. It seems like the uninstaller removes all the files that were originally installed from the MSI file. How do I do that?
Here are my files which I wish to keep it forever
<Binary Id="RootCABinary" SourceFile="Assets\Certificates\RootCA.cer" />
<Binary Id="SubCABinary" SourceFile="Assets\Certificates\SubCA.cer" />
I have used WixIIsExtension.dll to install these certificates to the windows store.
Overwrite: Is it important that the file never gets overwritten? If so, add
"Never Overwrite" to your component. WiX attribute: NeverOverwrite="yes". Remember to test upgrade scenarios!
Permanent Component: As stated by Pavel, you can set a component permanent:
<Component Permanent="yes">
<File Source="License.rtf" />
</Component>
Blank GUID: Another way to do it is to set a blank component GUID. It essentially means "install and then leave alone". No repair or uninstall should be done (remember to add NeverOverwrite="yes" if the file should never be overwritten):
<Component Guid="" Feature="MainApplication">
<File Source="SubCA.cer" KeyPath="yes" />
</Component>
Read-Only Copy: I sometimes install files to a per-machine path (for example somewhere under program files) and then copy them to a per-user location (somewhere in the user-profile) on application launch, and then do operations on them that entail that the files should not be deleted. This is good in cases where you want to do something that change the files in question (they need to be writable). Then it is good to "untangle" them from deployment concerns (files will not be meddled with by installer operations at all - the installer has no knowledge of them). The original read-only copy installed to program files can be uninstalled though (no longer needed?).
Other approaches: You can also create such files using custom actions during installation (usually text files only), you can download the file in question from your web site on application launch (makes the file easy to manage and update / replace? Vulnerable to connection problems - firewalls, etc...) and the application can create the file using "internal defaults" in the main executable on launch. And there are no doubt further approaches that I can't recall.
Put your binaries in a separate WiX component and make it permanent. Have a look at this thread as well

How to change directory in wxs file where all dll and other files will be installed?

I am quite new in creating setup project using .wxs file in .NET project. I knew that by default when you run MSI file it creates folder with this project and it's reference files (dll, exe, etc...) in C:\Program Files (x86). My question is, can I change this location in my .wxs file to another using XML.
ConfigurableDirectory: You can use the ConfigurableDirectory attribute of the Feature Element to set a configurable feature directory. See down the page in the screenshot section here: How to assign path value to Directory in WIX?.
Mock-up only:
Note: I am basing myself on the standard WiX Mondo dialog set. To hook up the Mondo dialogs, see this answer. Essentially, add reference to WixUIExtension.dll and insert the <UIRef Id="WixUI_Mondo" /> element. This will compile a default WiX dialog set into your MSI.
<Feature Id="MyFeature" Title="MyFeature" Level="1" ConfigurableDirectory="INSTALLFOLDER"></Feature>
<..>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="InstallDirConfigurableTesting">
Remember Property: Note that you must persist the custom directory location yourself to the registry and read back for major upgrades or else your whole product gets "moved" during upgrades (I know, it is weird). This persisting does not happen auto-magically in any way that I know about. You can persist the property and read it back using the "Remember Pattern" as described by WiX creator and benevolency Rob Mensching here: The WiX toolset's "Remember Property" pattern.
Implementation Tip: Testing the read-back of the directory property for major upgrade scenarios can be a bit fiddly. If you create a test project in Visual Studio using Votive you can use the trick to just compile version 1 of your MSI (now suffix your MSI file in the build output folder with _Version1.0.0.msi or similar), and then kick up one of the first three digits of the version number property and build an upgrade version (suffix with _Version2.0.0.msi or similar). Then you install in sequence selecting a custom installation directory and check whether your second setup correctly detects the modified path. Just use a mockup or test harness project with a single component in it to get this working, or else you could drive yourself mad if you have to compile your whole setup. Then just inject your finished markup into the main project. Obvious, yes - just mentioning.
Some Further Links:
How to use ProgramFiles64Folder in ConfigurableDirectory
What is the meaning of WiX configurable directory?

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.

WiX: how to pack exe or dll to use only during installation

I need to include a dll/exe in the resulting MSI (created through a WiX project), but I do not want to deploy them during installation: I only want to use them in some CustomAction my purpose is to include an existing exe/dll and call it during installation from wxs code (not from a CustomAction dll).
Is it possible to include files which are not deployed during installation? I mean, only pack them inside the resulting MSI, and call them for some task while they are unpacked inside %temp% folder?
Also, it would be nice if somebody could show some sample code of how to include dll/exe through the Product.wxs XML code unit.
Thanks.
Yes, include them using the Binary element.
<Binary Id='MyCustomActionBinary'
SourceFile='$(var.CustomActionProject.TargetPath)' />
This will make them available to your CustomAction where you can use the BinaryKey attribute to reference the Binary:
<CustomAction Id='MyCustomAction'
BinaryKey='MyCustomActionBinary'
DllEntry='MyCustomFunction'
Execute='deferred' />
If you are using C#/DTF to write a custom action, you simply add the DLL's as references. For any other kind of file you add them to the project as Content | CopyAlways and the build will automatically include these files in the self extracting custom action. They will be available in the current directory ( a temp directory) when the CA runs and automatically cleaned up when the CA ends.

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.