Add files in program data using wix - visual-studio-2012

I am developing an Outlook addin using addin express. I am using a .wxs file in my program's setup project. It helps me to install my program in roaming folder. I want to add Redemption.dll to the path C:\programData\Flow. So I modified the code as mentioned below. But it is not working. Please advice me.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
<!--Modified[Id]-->
<Product
Id="faa8e62a-0834-4efa-aad3-b2f7903a3a6c"
Name="FlowOutlook"
Language="1033"
Version="1.1.4"
Manufacturer="Default Company"
UpgradeCode="faa8e62a-0834-4efa-aad3-b2f7903a3a6d"
Codepage="1252">
<Package
InstallerVersion="200"
Compressed="yes"
InstallScope="perUser"
Description="FlowOutlook"
Manufacturer="Default Company"
Languages="1033"
SummaryCodepage="1252"
InstallPrivileges="limited"
/>
<!--Added-->
<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
<Upgrade Id="faa8e62a-0834-4efa-aad3-b2f7903a3a6d">
<!--Should be same as "UpgradeCode"-->
<UpgradeVersion
Minimum="1.0.0" Maximum="1.1.4"
Property="PREVIOUSVERSIONSINSTALLED"
IncludeMinimum="yes" IncludeMaximum="no" />
</Upgrade>
<!--Romoved-->
<!--<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />-->
<Media Id="1" Cabinet="FlowOutlook.cab" EmbedCab="yes" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<Feature Id="ProductFeature" Title="FlowOutlook" Level="1" ConfigurableDirectory="INSTALLFOLDER">
<ComponentRef Id="INSTALLFOLDER" />
<ComponentGroupRef Id="ProductComponents" />
<!--<ComponentRef Id="Redemption.dll" />-->
<!--Added-->
</Feature>
<UIRef Id="WixUI_InstallDir" />
<UIRef Id="WixUI_ErrorProgressText" />
<!-- Pics-->
<!-- Pics-->
<Binary Id="adxregistrator_exe" SourceFile="$(var.ADX_PATH)\Redistributables\adxregistrator.exe" />
<CustomAction Id="RegisterApp" BinaryKey="adxregistrator_exe" Execute="deferred" ExeCommand='/install="[INSTALLFOLDER]$(var.FlowOutlook.TargetFileName)" /privileges=user /returnExitCode=false' Impersonate="yes" />
<CustomAction Id="RollbackApp" BinaryKey="adxregistrator_exe" Execute="rollback" ExeCommand='/uninstall="[INSTALLFOLDER]$(var.FlowOutlook.TargetFileName)" /privileges=user' Impersonate="yes" Return="ignore" />
<CustomAction Id="UnregisterApp" BinaryKey="adxregistrator_exe" Execute="deferred" ExeCommand='/uninstall="[INSTALLFOLDER]$(var.FlowOutlook.TargetFileName)" /privileges=user' Impersonate="yes" Return="ignore" />
<!--Added-->
<CustomAction Id="RegisterRedemption32" Directory="INSTALLFOLDER" ExeCommand='regsvr32.exe "C:\ProgramData\Flow\Redemption.dll"'></CustomAction>
<!--self registering Redemption 32-bit -->
<CustomAction Id="UnregisterRedemption32" Directory="INSTALLFOLDER" ExeCommand='regsvr32.exe /u "C:\ProgramData\Flow\Redemption.dll"'></CustomAction>
<!--self unregistering Redemption 32-bit -->
<CustomAction Id="RegisterRedemption64" Directory="INSTALLFOLDER" ExeCommand='regsvr32.exe "C:\ProgramData\Flow\Redemption64.dll"'></CustomAction>
<!--self registering Redemption 64-bit -->
<CustomAction Id="UnregisterRedemption64" Directory="INSTALLFOLDER" ExeCommand='regsvr32.exe /u "C:\ProgramData\Flow\Redemption64.dll"'></CustomAction>
<!--self unregistering Redemption 64-bit -->
<!--Added-->
<InstallExecuteSequence>
<Custom Action="RegisterApp" After="StartServices"><![CDATA[$ProductComponent>2]]></Custom>
<Custom Action="RollbackApp" After="RegisterApp"><![CDATA[$ProductComponent>2]]></Custom>
<Custom Action="UnregisterApp" After="MsiUnpublishAssemblies"><![CDATA[$ProductComponent=2]]></Custom>
<!--Added-->
<RemoveExistingProducts Before="InstallInitialize" />
<Custom Action="RegisterRedemption32" After="InstallFinalize">NOT Installed</Custom>
<!--self registering Redemption 32-bit-->
<Custom Action="UnregisterRedemption32" After="InstallFinalize">REMOVE="ALL"</Custom>
<!--self unregistering Redemption 32-bit-->
<Custom Action="RegisterRedemption64" After="InstallFinalize">NOT Installed</Custom>
<!--self registering Redemption 64-bit-->
<Custom Action="UnregisterRedemption64" After="InstallFinalize">REMOVE="ALL"</Custom>
<!--self unregistering Redemption 64-bit-->
<!--Added-->
</InstallExecuteSequence>
<!-- Properties for all current versions of the .NET Framework are available here: http://wix.sourceforge.net/manual-wix3/wixnetfxextension.htm -->
<PropertyRef Id="NETFRAMEWORK40CLIENT"/>
<Condition Message="This application requires .NET Framework 4.0. Please install the .NET Framework then run this installer again.">
<![CDATA[Installed OR NETFRAMEWORK40CLIENT]]>
</Condition>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="AppDataFolder">
<Directory Id="INSTALLFOLDER" Name="FlowOutlook" >
<Component Id="INSTALLFOLDER" Guid="cdca45fb-ce6c-4a00-9865-29b24123c62a">
<RemoveFolder On="both" Id="INSTALLFOLDER"/>
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[ProductName]" Type="string" Value="FlowOutlook" />
</Component>
</Directory>
</Directory>
</Directory>
</Fragment>
<Fragment>
<Directory Id="TARGETDIR2" Name="SourceDir2">
<Directory Id="ProgramFilesFolder">
<Directory Id="APPLICATIONROOTDIRECTORY" Name="Flow"/>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" >
<Component Id="ProductComponent" Guid="2596359b-ed35-42f1-be52-2ff4625189f5" DiskId="1" Directory="INSTALLFOLDER" >
<RegistryKey Root="HKCU" Key="Software\[Manufacturer]\[ProductName]">
<RegistryValue Type="string" Name="Installed" Value="[INSTALLFOLDER]" KeyPath="yes" />
</RegistryKey>
<File Id="_$(var.FlowOutlook.TargetName)_dll" Name="$(var.FlowOutlook.TargetFileName)" Source="$(var.FlowOutlook.TargetPath)" />
<File Id="_adxloader_dll_manifest" Name="adxloader.dll.manifest" Source="$(var.FlowOutlook.ProjectDir)Loader\" />
<File Id="_adxloader_dll" Name="adxloader.dll" Source="$(var.FlowOutlook.ProjectDir)Loader\" />
<File Id="_adxloader64_dll" Name="adxloader64.dll" Source="$(var.FlowOutlook.ProjectDir)Loader\" />
<File Id="_AddinExpress_MSO_2005_dll" Name="AddinExpress.MSO.2005.dll" Source="C:\Program Files (x86)\Add-in Express\Add-in Express for .NET\Bin\" />
<File Id="_AddinExpress_OL_2005_dll" Name="AddinExpress.OL.2005.dll" Source="C:\Program Files (x86)\Add-in Express\Add-in Express for .NET\Bin\" />
<File Id="_Newtonsoft_Json_dll" Name="Newtonsoft.Json.dll" Source="$(var.FlowOutlook.TargetDir)" />
<File Id="_Microsoft_Vbe_Interop_dll" Name="Microsoft.Vbe.Interop.dll" Source="$(var.FlowOutlook.TargetDir)" />
<File Id="_Newtonsoft_Json_pdb" Name="Newtonsoft.Json.pdb" Source="$(var.FlowOutlook.TargetDir)" />
<File Id="_Newtonsoft_Json_xml" Name="Newtonsoft.Json.xml" Source="$(var.FlowOutlook.TargetDir)" />
<File Id="_Redemption_dll" Name="Redemption.dll" Source="$(var.FlowOutlook.TargetDir2)" />
<File Id="_Newtonsoft_Json_xml" Name="Redemption64.dll" Source="$(var.FlowOutlook.TargetDir2)" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
Thanks for helping. Kushan Randima

The C:\ drive requires admin privileges for writing. You need to run the installer elevated (Run As Admin).

To do this, I had to create another element as a child element of and I had to add some extra code under . Please see below code to see working solution.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:netfx="http://schemas.microsoft.com/wix/NetFxExtension">
<!--Modified[Id]-->
<Product
Id="faa8e62a-0834-4efa-aad3-b2f7903a3a6c"
Name="FlowOutlook"
Language="1033"
Version="1.1.5"
Manufacturer="Default Company"
UpgradeCode="faa8e62a-0834-4efa-aad3-b2f7903a3a6d"
Codepage="1252">
<Package
InstallerVersion="200"
Compressed="yes"
InstallScope="perUser"
Description="FlowOutlook"
Manufacturer="Default Company"
Languages="1033"
SummaryCodepage="1252"
InstallPrivileges="limited"
/>
<!--Added-->
<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />
<Upgrade Id="faa8e62a-0834-4efa-aad3-b2f7903a3a6d">
<!--Should be same as "UpgradeCode"-->
<UpgradeVersion
Minimum="1.0.0" Maximum="1.1.5"
Property="PREVIOUSVERSIONSINSTALLED"
IncludeMinimum="yes" IncludeMaximum="no" />
</Upgrade>
<!--Romoved-->
<!--<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />-->
<Media Id="1" Cabinet="FlowOutlook.cab" EmbedCab="yes" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<Feature Id="ProductFeature" Title="FlowOutlook" Level="1" ConfigurableDirectory="INSTALLFOLDER">
<ComponentRef Id="INSTALLFOLDER" />
<ComponentGroupRef Id="ProductComponents" />
<!--<ComponentRef Id="Redemption.dll" />-->
<!--Added-->
</Feature>
<UIRef Id="WixUI_InstallDir" />
<UIRef Id="WixUI_ErrorProgressText" />
<!-- Pics-->
<!-- Pics-->
<Binary Id="adxregistrator_exe" SourceFile="$(var.ADX_PATH)\Redistributables\adxregistrator.exe" />
<CustomAction Id="RegisterApp" BinaryKey="adxregistrator_exe" Execute="deferred" ExeCommand='/install="[INSTALLFOLDER]$(var.FlowOutlook.TargetFileName)" /privileges=user /returnExitCode=false' Impersonate="yes" />
<CustomAction Id="RollbackApp" BinaryKey="adxregistrator_exe" Execute="rollback" ExeCommand='/uninstall="[INSTALLFOLDER]$(var.FlowOutlook.TargetFileName)" /privileges=user' Impersonate="yes" Return="ignore" />
<CustomAction Id="UnregisterApp" BinaryKey="adxregistrator_exe" Execute="deferred" ExeCommand='/uninstall="[INSTALLFOLDER]$(var.FlowOutlook.TargetFileName)" /privileges=user' Impersonate="yes" Return="ignore" />
<!--Added-->
<!--self registering Redemption 32-bit -->
<CustomAction Id="RegisterRedemption32" Directory="INSTALLFOLDER" ExeCommand='regsvr32.exe /s "C:\ProgramData\Flow\Redemption.dll"'></CustomAction>
<!--self unregistering Redemption 32-bit -->
<CustomAction Id="UnregisterRedemption32" Directory="INSTALLFOLDER" ExeCommand='regsvr32.exe /s /u "C:\ProgramData\Flow\Redemption.dll"'></CustomAction>
<!--self registering Redemption 64-bit -->
<CustomAction Id="RegisterRedemption64" Directory="INSTALLFOLDER" ExeCommand='regsvr32.exe /s "C:\ProgramData\Flow\Redemption64.dll"'></CustomAction>
<!--self unregistering Redemption 64-bit -->
<CustomAction Id="UnregisterRedemption64" Directory="INSTALLFOLDER" ExeCommand='regsvr32.exe /s /u "C:\ProgramData\Flow\Redemption64.dll"'></CustomAction>
<!--Added-->
<InstallExecuteSequence>
<Custom Action="RegisterApp" After="StartServices"><![CDATA[$ProductComponent>2]]></Custom>
<Custom Action="RollbackApp" After="RegisterApp"><![CDATA[$ProductComponent>2]]></Custom>
<Custom Action="UnregisterApp" After="MsiUnpublishAssemblies"><![CDATA[$ProductComponent=2]]></Custom>
<!--Added-->
<RemoveExistingProducts Before="InstallInitialize" />
<!--self registering Redemption 32-bit-->
<Custom Action="RegisterRedemption32" After="InstallFinalize">NOT Installed</Custom>
<!--self unregistering Redemption 32-bit-->
<Custom Action="UnregisterRedemption32" After="InstallFinalize">REMOVE="ALL"</Custom>
<!--self registering Redemption 64-bit-->
<Custom Action="RegisterRedemption64" After="InstallFinalize">NOT Installed</Custom>
<!--self unregistering Redemption 64-bit-->
<Custom Action="UnregisterRedemption64" After="InstallFinalize">REMOVE="ALL"</Custom>
<!--Added-->
</InstallExecuteSequence>
<!-- Properties for all current versions of the .NET Framework are available here: http://wix.sourceforge.net/manual-wix3/wixnetfxextension.htm -->
<PropertyRef Id="NETFRAMEWORK40CLIENT"/>
<Condition Message="This application requires .NET Framework 4.0. Please install the .NET Framework then run this installer again.">
<![CDATA[Installed OR NETFRAMEWORK40CLIENT]]>
</Condition>
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="AppDataFolder">
<Directory Id="INSTALLFOLDER" Name="FlowOutlook" >
<Component Id="INSTALLFOLDER" Guid="cdca45fb-ce6c-4a00-9865-29b24123c62a">
<RemoveFolder On="both" Id="INSTALLFOLDER"/>
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[ProductName]" Type="string" Value="FlowOutlook" />
</Component>
</Directory>
</Directory>
<!-- Reference the Program Files folder -->
<Directory Id="CommonAppDataFolder">
<Directory Id="APPLICATIONDATADIRECTORY" Name="Flow"/>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" >
<Component Id="ProductComponent" Guid="2596359b-ed35-42f1-be52-2ff4625189f5" DiskId="1" Directory="INSTALLFOLDER" >
<RegistryKey Root="HKCU" Key="Software\[Manufacturer]\[ProductName]">
<RegistryValue Type="string" Name="Installed" Value="[INSTALLFOLDER]" KeyPath="yes" />
</RegistryKey>
<File Id="_$(var.FlowOutlook.TargetName)_dll" Name="$(var.FlowOutlook.TargetFileName)" Source="$(var.FlowOutlook.TargetPath)" />
<File Id="_adxloader_dll_manifest" Name="adxloader.dll.manifest" Source="$(var.FlowOutlook.ProjectDir)Loader\" />
<File Id="_adxloader_dll" Name="adxloader.dll" Source="$(var.FlowOutlook.ProjectDir)Loader\" />
<File Id="_adxloader64_dll" Name="adxloader64.dll" Source="$(var.FlowOutlook.ProjectDir)Loader\" />
<File Id="_AddinExpress_MSO_2005_dll" Name="AddinExpress.MSO.2005.dll" Source="C:\Program Files (x86)\Add-in Express\Add-in Express for .NET\Bin\" />
<File Id="_AddinExpress_OL_2005_dll" Name="AddinExpress.OL.2005.dll" Source="C:\Program Files (x86)\Add-in Express\Add-in Express for .NET\Bin\" />
<File Id="_Newtonsoft_Json_dll" Name="Newtonsoft.Json.dll" Source="$(var.FlowOutlook.TargetDir)" />
<File Id="_Microsoft_Vbe_Interop_dll" Name="Microsoft.Vbe.Interop.dll" Source="$(var.FlowOutlook.TargetDir)" />
<File Id="_Newtonsoft_Json_pdb" Name="Newtonsoft.Json.pdb" Source="$(var.FlowOutlook.TargetDir)" />
<File Id="_Newtonsoft_Json_xml" Name="Newtonsoft.Json.xml" Source="$(var.FlowOutlook.TargetDir)" />
</Component>
<Component Id="ProductComponent2" Guid="2596359b-ed35-42f1-be52-2ff4625189f6" DiskId="1" Directory="APPLICATIONDATADIRECTORY" >
<File Id="_Redemption_dll" Name="Redemption.dll" Source="$(var.FlowOutlook.TargetDir)" />
<File Id="_Redemption64.dll" Name="Redemption64.dll" Source="$(var.FlowOutlook.TargetDir)" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>

You need to use the Windows Installer property CommonAppDataFolder in a directory element that is a child of the TARGETDIR directory element. Then create a child directory element beneath this for your company name and use this directory element in your component authoring.
FWIW I maintain an open source project called ISWIX that makes this as easy as right click select CommonAppDataFolder right click new subfolder followed by typing the name and then dragging your content into that folder and clicking save.

Related

Wix MSI Installer:How to allow anonymous authentication when set to override="deny" in applicationHost.Config

I have a web application that we install via a Wix MSI project. The web.config includes the authentication nodes below. Everything installs correctly but after installation, I get the error message:
"The configuration section cannot be used at this path". This is due to the configuration locking in applicationHost.config .
<system.webServer>
<security>
<authentication>
<anonymousAuthentication enabled="false" />
<basicAuthentication enabled="true" />
<windowsAuthentication enabled="false" />
</authentication>
</security>
</system.webServer>
How can I override the applicationHost.config settings during the installation? I do install required Windows Features during the install, but am I missing one?
This is the solution that worked for me, calling appcmd from a custom action, before InstallFinalize.
<CustomAction Id="UnlockAnonymousAuthentication"
Execute="deferred"
Impersonate="no"
Return="check"
Directory="TARGETDIR"
ExeCommand="[SystemFolder]inetsrv\appcmd unlock config /section:anonymousAuthentication" />
<CustomAction Id="UnlockBasicAuthentication"
Execute="deferred"
Impersonate="no"
Return="check"
Directory="TARGETDIR"
ExeCommand="[SystemFolder]inetsrv\appcmd unlock config /section:basicAuthentication" />
<CustomAction Id="UnlockWindowsAuthentication"
Execute="deferred"
Impersonate="no"
Return="check"
Directory="TARGETDIR"
ExeCommand="[SystemFolder]inetsrv\appcmd unlock config /section:windowsAuthentication" />
<InstallExecuteSequence>
<Custom Action="UnlockAnonymousAuthentication" Before="InstallFinalize"><![CDATA[NOT Installed]]></Custom>
<Custom Action="UnlockBasicAuthentication" Before="InstallFinalize"><![CDATA[NOT Installed]]></Custom>
<Custom Action="UnlockWindowsAuthentication" Before="InstallFinalize"><![CDATA[NOT Installed]]></Custom>
</InstallExecuteSequence>
Hope this helps someone.
Here is currently a way to do this directly using the WiX IIS extension WebDirProperties element:
https://wixtoolset.org/documentation/manual/v3/xsd/iis/webdirproperties.html
Something similar to this should work. Notice the critical piece is the WebDirProperties
element that specifies the
AnonymousAccess="yes" BasicAuthentication="no" WindowsAuthentication="no" which modify
the IIS properties you are looking to change during installation.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension" >
<Fragment>
<!-- Install to default web site -->
<iis:WebSite Id="DefaultWebSite" Description='Default Web Site'>
<iis:WebAddress Id="AllUnassigned" Port="80" />
</iis:WebSite>
<!-- References the installation folder specified in the Product.wxs file under the INSTALLFOLDER -->
<DirectoryRef Id="WEB_INSTALLFOLDER">
<!-- Configure virtual dir -->
<Component Id="VirtualDirectoryComponent"
Guid="{INSERT-YOUR-OWN-GUID-2C27-427A-A7B1-DA4DBCC79117}"
KeyPath="yes" >
<iis:WebVirtualDir Id="VirtualDirectory"
Alias="[WEB_DIRECTORY_ALIAS]" Directory="WEB_INSTALLFOLDER"
WebSite="DefaultWebSite">
<iis:WebDirProperties Id="VirtualDirectoryProperties"
AnonymousAccess="yes" BasicAuthentication="no"
WindowsAuthentication="no" />
<iis:WebApplication
Id="MyWebApplication"
Name="MyWebApplication" />
</iis:WebVirtualDir>
</Component>
</DirectoryRef>
</Fragment>
</Wix>

WixToolset directory structure copy

I have a task to create installation for nodejs web application. I have found the solution to compress the whole application copy it as one file with Wix and extract it with wix custom actions. This works. But its downside is that targt server has to have compressing software installed. In this case 7z.
Watching other installations, they are extracting files with out any external software.
I have investigate a wix a bit it says that I should use HEAT, nut I am not sure what it that. There any simple start examples, where I can understand it conceptually. I have found out also that other guys out there have slow learning curve on Wix. I am quite serious in learning this but I need a little push. I would like to start from this example.
How to whole folder copy with wix? or what it best practice with. Maybe some compressing with out third party software.
EDIT:
Here is how my wixproj file looks like:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<ProductVersion>3.10</ProductVersion>
<ProjectGuid>a42f686d-72e6-4452-b066-796c441e0d65</ProjectGuid>
<SchemaVersion>2.0</SchemaVersion>
<OutputName>SomeManager</OutputName>
<OutputType>Package</OutputType>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' AND '$(MSBuildExtensionsPath32)' != '' ">$(MSBuildExtensionsPath32)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
<WixTargetsPath Condition=" '$(WixTargetsPath)' == '' ">$(MSBuildExtensionsPath)\Microsoft\WiX\v3.x\Wix.targets</WixTargetsPath>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
<DefineConstants>Debug</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<OutputPath>bin\$(Configuration)\</OutputPath>
<IntermediateOutputPath>obj\$(Configuration)\</IntermediateOutputPath>
</PropertyGroup>
<ItemGroup>
<Compile Include="Product.wxs" />
</ItemGroup>
<ItemGroup>
<Content Include="google-credentials-release-server.p12" />
<Content Include="LICENSE.rtf" />
<Content Include="some_service.tar.gz">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="XSLT\readme.txt" />
<Content Include="XSLT\RegisterForCOM.xml" />
<Content Include="XSLT\XslFile.xslt" />
<Content Include="XSLT\XslProjectOutput.xslt" />
<Content Include="XSLT\XslRegisterForCOM.xslt" />
<Content Include="XSLT\_ERMPanel.xml" />
</ItemGroup>
<ItemGroup>
<WixExtension Include="WixUtilExtension">
<HintPath>$(WixExtDir)\WixUtilExtension.dll</HintPath>
<Name>WixUtilExtension</Name>
</WixExtension>
<WixExtension Include="WixUIExtension">
<HintPath>$(WixExtDir)\WixUIExtension.dll</HintPath>
<Name>WixUIExtension</Name>
</WixExtension>
</ItemGroup>
<ItemGroup>
<Folder Include="XSLT\" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ERMPanel\ERMPanel.csproj">
<Name>ERMPanel</Name>
<Project>{F62EB2B5-967E-4E32-BE06-89248AFA3385}</Project>
<Private>True</Private>
<DoNotHarvest>
</DoNotHarvest>
<RefProjectOutputGroups>Binaries</RefProjectOutputGroups>
<RefTargetDir>INSTALLDIR</RefTargetDir>
</ProjectReference>
</ItemGroup>
<Import Project="$(WixTargetsPath)" />
<Target Name="BeforeBuild">
<MakeDir Directories="$(IntermediateOutputPath)Harvested XML" />
<MakeDir Directories="$(IntermediateOutputPath)Harvested Output" />
<XslTransformation XmlInputPaths="XSLT\RegisterForCOM.xml" XslInputPath="XSLT\XslRegisterForCOM.xslt" OutputPaths="$(IntermediateOutputPath)_COMFiles.txt" Parameters="<Parameter Name='operationType' Value='HeatFiles'/><Parameter Name='intermediateDir' Value='$(IntermediateOutputPath)'/>" Condition="$(MSBuildToolsVersion) <= 12" />
<XslTransformation XmlInputPaths="XSLT\RegisterForCOM.xml" XslInputPath="XSLT\XslRegisterForCOM.xslt" UseTrustedSettings="true" OutputPaths="$(IntermediateOutputPath)_COMFiles.txt" Parameters="<Parameter Name='operationType' Value='HeatFiles'/><Parameter Name='intermediateDir' Value='$(IntermediateOutputPath)'/>" Condition="$(MSBuildToolsVersion) >= 14" />
<ReadLinesFromFile File="$(IntermediateOutputPath)_COMFiles.txt">
<Output TaskParameter="Lines" ItemName="COMFilelist" />
</ReadLinesFromFile>
<ConvertToAbsolutePath Paths="#(COMFilelist)">
<Output TaskParameter="AbsolutePaths" ItemName="ResolvedCOMFilelist" />
</ConvertToAbsolutePath>
<Exec Command=""$(Wix)Bin\heat.exe" file "%(ResolvedCOMFilelist.Identity)" -sw -gg -sfrag -nologo -srd -out "$(IntermediateOutputPath)Harvested XML\_%(Filename).com.xml"" IgnoreExitCode="false" WorkingDirectory="$(MSBuildProjectDirectory)" Condition="'%(ResolvedCOMFilelist.Identity)'!=''" />
<XslTransformation XmlInputPaths="XSLT\RegisterForCOM.xml" XslInputPath="XSLT\XslRegisterForCOM.xslt" OutputPaths="$(IntermediateOutputPath)_COMFiles.txt" Parameters="<Parameter Name='operationType' Value='TransformFiles'/><Parameter Name='intermediateDir' Value='$(IntermediateOutputPath)Harvested XML\'/>" Condition="$(MSBuildToolsVersion) <= 12" />
<XslTransformation XmlInputPaths="XSLT\RegisterForCOM.xml" XslInputPath="XSLT\XslRegisterForCOM.xslt" UseTrustedSettings="true" OutputPaths="$(IntermediateOutputPath)_COMFiles.txt" Parameters="<Parameter Name='operationType' Value='TransformFiles'/><Parameter Name='intermediateDir' Value='$(IntermediateOutputPath)Harvested XML\'/>" Condition="$(MSBuildToolsVersion) >= 14" />
<ReadLinesFromFile File="$(IntermediateOutputPath)_COMFiles.txt">
<Output TaskParameter="Lines" ItemName="XMLFileList" />
</ReadLinesFromFile>
<XslTransformation XmlInputPaths="%(XMLFileList.Identity)" XslInputPath="XSLT\XslFile.xslt" OutputPaths="$(IntermediateOutputPath)Harvested Output\%(Filename).wsx" Parameters="<Parameter Name='sourceFilePath' Value='%(XMLFileList.Identity)'/>" Condition="'%(XMLFileList.Identity)'!='' And $(MSBuildToolsVersion) <= 12" />
<XslTransformation XmlInputPaths="%(XMLFileList.Identity)" XslInputPath="XSLT\XslFile.xslt" UseTrustedSettings="true" OutputPaths="$(IntermediateOutputPath)Harvested Output\%(Filename).wsx" Parameters="<Parameter Name='sourceFilePath' Value='%(XMLFileList.Identity)'/>" Condition="'%(XMLFileList.Identity)'!='' And $(MSBuildToolsVersion) >= 14" />
<Exec Command=""$(Wix)Bin\heat.exe" project "%(ProjectReference.FullPath)" -projectname "%(ProjectReference.Name)" -pog %(ProjectReference.RefProjectOutputGroups) -gg -sfrag -nologo -out "$(IntermediateOutputPath)Harvested XML\_%(ProjectReference.Name).xml"" IgnoreExitCode="false" WorkingDirectory="$(MSBuildProjectDirectory)" Condition="'%(ProjectReference.FullPath)'!='' And '%(ProjectReference.DoNotHarvest)'!='True' And '%(ProjectReference.ImportedFromVDProj)'=='True'" />
<HeatProject Project="%(ProjectReference.FullPath)" ProjectName="%(ProjectReference.Name)" OutputFile="$(IntermediateOutputPath)Harvested XML\_%(ProjectReference.Name).xml" ProjectOutputGroups="%(ProjectReference.RefProjectOutputGroups)" ToolPath="$(Wix)Bin\" SuppressAllWarnings="true" AutogenerateGuids="false" GenerateGuidsNow="true" SuppressFragments="true" SuppressUniqueIds="false" Condition="'%(ProjectReference.FullPath)'!='' And '%(ProjectReference.DoNotHarvest)'!='True' And '%(ProjectReference.ImportedFromVDProj)'!='True'" />
<XslTransformation XmlInputPaths="$(IntermediateOutputPath)Harvested XML\_%(ProjectReference.Name).xml" XslInputPath="XSLT\XslProjectOutput.xslt" OutputPaths="$(IntermediateOutputPath)Harvested Output\_%(ProjectReference.Name).wxs" Parameters="<Parameter Name='projectName' Value='%(ProjectReference.Name)'/><Parameter Name='projectFilePath' Value='%(ProjectReference.FullPath)'/><Parameter Name='intermediateDir' Value='$(IntermediateOutputPath)Harvested Output\'/>" Condition="'%(ProjectReference.FullPath)'!='' And '%(ProjectReference.DoNotHarvest)'!='True' And Exists('$(IntermediateOutputPath)Harvested XML\_%(ProjectReference.Name).xml') And $(MSBuildToolsVersion) <= 12" />
<XslTransformation XmlInputPaths="$(IntermediateOutputPath)Harvested XML\_%(ProjectReference.Name).xml" XslInputPath="XSLT\XslProjectOutput.xslt" UseTrustedSettings="true" OutputPaths="$(IntermediateOutputPath)Harvested Output\_%(ProjectReference.Name).wxs" Parameters="<Parameter Name='projectName' Value='%(ProjectReference.Name)'/><Parameter Name='projectFilePath' Value='%(ProjectReference.FullPath)'/><Parameter Name='intermediateDir' Value='$(IntermediateOutputPath)Harvested Output\'/>" Condition="'%(ProjectReference.FullPath)'!='' And '%(ProjectReference.DoNotHarvest)'!='True' And Exists('$(IntermediateOutputPath)Harvested XML\_%(ProjectReference.Name).xml') And $(MSBuildToolsVersion) >= 14" />
<XslTransformation XmlInputPaths="XSLT\RegisterForCOM.xml" XslInputPath="XSLT\XslRegisterForCOM.xslt" OutputPaths="$(IntermediateOutputPath)_COMFiles.txt" Parameters="<Parameter Name='operationType' Value='CompileFiles'/><Parameter Name='intermediateDir' Value='$(IntermediateOutputPath)Harvested Output\'/>" Condition="$(MSBuildToolsVersion) <= 12" />
<XslTransformation XmlInputPaths="XSLT\RegisterForCOM.xml" XslInputPath="XSLT\XslRegisterForCOM.xslt" UseTrustedSettings="true" OutputPaths="$(IntermediateOutputPath)_COMFiles.txt" Parameters="<Parameter Name='operationType' Value='CompileFiles'/><Parameter Name='intermediateDir' Value='$(IntermediateOutputPath)Harvested Output\'/>" Condition="$(MSBuildToolsVersion) >= 14" />
<ReadLinesFromFile File="$(IntermediateOutputPath)_COMFiles.txt">
<Output TaskParameter="Lines" ItemName="WSXFileList" />
</ReadLinesFromFile>
<CreateItem Include="$(IntermediateOutputPath)Harvested Output\_%(ProjectReference.Name).wxs" Condition="'%(ProjectReference.FullPath)'!='' And '%(ProjectReference.DoNotHarvest)'!='True' And Exists('$(IntermediateOutputPath)Harvested Output\_%(ProjectReference.Name).wxs')">
<Output TaskParameter="Include" ItemName="Compile" />
</CreateItem>
<CreateItem Include="#(WSXFileList)" Condition="Exists('%(WSXFileList.Identity)')">
<Output TaskParameter="Include" ItemName="Compile" />
</CreateItem>
</Target>
<!--
To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Wix.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>
Here is Product.wsx file:
<?xml version="1.0" encoding="utf-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Product Id="*" Name="SomeManager" Language="1033" Version="1.0.0.2" Manufacturer="Certus" UpgradeCode="4810b5e4-21d8-4a45-b289-eafb10dddc0a">
<Package InstallerVersion="200" Compressed="yes" InstallScope="perMachine" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<Media Id="1" Cabinet="Cab1.cab" EmbedCab="yes" />
<Feature Id="ProductFeature" Title="SomeInstaller" Level="1">
<ComponentGroupRef Id="ProductComponents" />
<ComponentGroupRef Id="ERMPanel.Binaries" />
<ComponentRef Id="comp_5D704CE7_9E55_4FC5_8CB2_6BA4612D6D35" />
<ComponentRef Id="comp_C9901889_BAD5_4B2C_9407_EAF967B1526C" />
<ComponentRef Id="comp_03332461_4D6C_4BB5_90D1_4C4D896D7775" />
<ComponentRef Id="comp_3AE770A3_904C_4458_81BD_300F195A4250" />
<ComponentRef Id="comp_dir_8F9BAB58_4415_4353_BE9E_36C8F7EEF78A" />
</Feature>
<UIRef Id="WixUI_InstallDir" />
<WixVariable Id="WixUILicenseRtf" Value="LICENSE.rtf" />
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLFOLDER" />
<CustomAction Id="ExtractService" Directory="INSTALLFOLDER" Impersonate="no" Execute="deferred" ExeCommand="7z e -y some_service.tar.gz" Return="check" />
<CustomAction Id="ExtractService2" Directory="INSTALLFOLDER" Impersonate="no" Execute="deferred" ExeCommand="7z x -y some_service.tar" Return="check" />
<!--<CustomAction Id="Create_Some_Files" Directory="INSTALLFOLDER" ExeCommand="cmd /C "mkdir some_files"" Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />
<CustomAction Id="Copy_p12" Directory="INSTALLFOLDER" ExeCommand="cmd /C "xcopy google-credentials-release-server.p12 some_files"" Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />-->
<!--<CustomAction Id="Create_Log" Directory="INSTALLFOLDER" ExeCommand="cmd /C "mkdir Logs"" Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />-->
<CustomAction Id="Cleanup_tarfile" Directory="INSTALLFOLDER" ExeCommand="cmd /C "del some_service.tar"" Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />
<CustomAction Id="Cleanup_targzfile" Directory="INSTALLFOLDER" ExeCommand="cmd /C "del some_service.tar.gz"" Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />
<CustomAction Id="Cleanup_bundle" Directory="INSTALLFOLDER" ExeCommand="cmd /C RD "[INSTALLFOLDER]" /s /q" Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />
<!--<CustomAction Id="Cleanup_Some_Files" Directory="INSTALLFOLDER" ExeCommand="cmd /C RD "some_files" /s /q" Execute="deferred" Return="ignore" HideTarget="no" Impersonate="no" />-->
<InstallExecuteSequence>
<Custom Action="ExtractService" Before="InstallFinalize">NOT Installed</Custom>
<Custom Action="ExtractService2" After="ExtractService">NOT Installed</Custom>
<!--<Custom Action="Create_Some_Files" After="ExtractService">NOT Installed</Custom>
<Custom Action="Copy_p12" After="Create_Some_Files">NOT Installed</Custom>-->
<!--<Custom Action="Create_Log" After="ExtractService2">NOT Installed</Custom>-->
<Custom Action="Cleanup_tarfile" Before="RemoveFiles">REMOVE="ALL"</Custom>
<Custom Action="Cleanup_targzfile" Before="RemoveFiles">REMOVE="ALL"</Custom>
<Custom Action="Cleanup_bundle" Before="RemoveFiles">REMOVE="ALL"</Custom>
<!--<Custom Action="Cleanup_Some_Files" Before="RemoveFiles">REMOVE="ALL"</Custom>-->
</InstallExecuteSequence>
<UI />
</Product>
<Fragment>
<Directory Id="TARGETDIR" Name="SourceDir">
<Directory Id="ProgramFilesFolder">
<Directory Id="INSTALLFOLDER" Name="SomeInstaller">
<Directory Id="ERMPanel.Binaries" />
<Directory Id="dir_585C16B3_5205_4D63_87F5_D7576697D2A9" Name="some_files">
<Component Id="comp_3AE770A3_904C_4458_81BD_300F195A4250" Guid="E117F3ED-771F-4547-9713-4A8FCDF173C8" Permanent="no" SharedDllRefCount="no" Transitive="no">
<File Id="_95238475_7B18_4058_82A2_B56483BCEFD1" DiskId="1" Hidden="no" ReadOnly="no" TrueType="no" System="no" Vital="yes" Name="google-credentials-release-server.p12" Source="google-credentials-release-server.p12" KeyPath="yes" />
</Component>
</Directory>
<Directory Id="dir_8F9BAB58_4415_4353_BE9E_36C8F7EEF78A" Name="Logs">
<Component Id="comp_dir_8F9BAB58_4415_4353_BE9E_36C8F7EEF78A" Guid="2EB4F74F-2FF4-42A6-B149-746C25950972" KeyPath="yes">
<CreateFolder Directory="dir_8F9BAB58_4415_4353_BE9E_36C8F7EEF78A" />
<RemoveFolder Id="id_026B5F17_73B3_4F92_803A_7ED05A3E3D7A" On="uninstall" Directory="dir_8F9BAB58_4415_4353_BE9E_36C8F7EEF78A" />
</Component>
</Directory>
</Directory>
</Directory>
<Directory Id="DesktopFolder">
<Component Id="comp_5D704CE7_9E55_4FC5_8CB2_6BA4612D6D35" Guid="32628FC1-02E6-486C-88BD-1E1B3EB24E44" Permanent="no" SharedDllRefCount="no" Transitive="no">
<Shortcut Id="_337FA89F_92ED_457C_899C_5344A548FD97" Directory="DesktopFolder" Name="ERMPanel" Show="normal" Target="[INSTALLFOLDER]ERMPanel.exe" WorkingDirectory="INSTALLFOLDER" />
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[ProductName]\Installer" Name="comp_5D704CE7_9E55_4FC5_8CB2_6BA4612D6D35" Type="string" Value="User's Desktop directory" KeyPath="yes" />
</Component>
</Directory>
<Directory Id="StartMenuFolder">
<Component Id="comp_03332461_4D6C_4BB5_90D1_4C4D896D7775" Guid="98E2BC79-8D59-4FEF-B235-92BB611CC608" Permanent="no" SharedDllRefCount="no" Transitive="no">
<Shortcut Id="_69EBF121_EA14_40B0_A587_1F520C033E45" Directory="StartMenuFolder" Name="ERMPanel" Show="normal" Target="[INSTALLFOLDER]ERMPanel.exe" WorkingDirectory="INSTALLFOLDER" />
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[ProductName]\Installer" Name="comp_03332461_4D6C_4BB5_90D1_4C4D896D7775" Type="string" Value="User's Start Menu directory" KeyPath="yes" />
</Component>
</Directory>
<Directory Id="ProgramMenuFolder">
<Component Id="comp_C9901889_BAD5_4B2C_9407_EAF967B1526C" Guid="AAA016CC-1B36-417A-A5EA-CB92A1A440AF" Permanent="no" SharedDllRefCount="no" Transitive="no">
<Shortcut Id="_3732D7A6_3230_4CCB_8037_3DA1D02E98E6" Directory="ProgramMenuFolder" Name="ERMPanel" Show="normal" Target="[INSTALLFOLDER]ERMPanel.exe" WorkingDirectory="INSTALLFOLDER" />
<RegistryValue Root="HKCU" Key="Software\[Manufacturer]\[ProductName]\Installer" Name="comp_C9901889_BAD5_4B2C_9407_EAF967B1526C" Type="string" Value="User's Programs Menu directory" KeyPath="yes" />
</Component>
</Directory>
</Directory>
</Fragment>
<Fragment>
<ComponentGroup Id="ProductComponents" Directory="INSTALLFOLDER">
<Component Id="packages" Guid="">
<File Source="some_service.tar.gz" />
</Component>
</ComponentGroup>
</Fragment>
</Wix>
What I am doing is manually compressing node application into file some_service.tar.gz, then I copy it as a single file, and extract it in custom actions. Of course that is wrong. I would like to have just nodejsdir on the same place as some_service.tar.gz and copy it with heat.exe
I must admit I find this quite confusing, if you could help me please based on my example.
Thank you.
Heat is just the harvesting tool included in wix. You can use it to harvest hundreds of files automatically if you have the directory structure on your build machine that you want to replicate on the install machine.
If your included files change rather frequently, setting up a heat task to run every build is something you should do. If the files included are rather static and you only add/remove or move some files infrequently, use heat to generate the first WXS with all the files and then manually update it when required.
Don't forget that the msi already compresses all the files it includes, there's no reason to compress all the files into a zip then include that into your msi only to unpack it after "installing" it. You just end up taking way too much space unnecessarily on the customer's machine and may fail to install since the MSI cannot properly do the file costing and may run out of disk space when unpacking.
You also forego all the useful file tracking and handling features of the windows installer when you use a zip containing all your files. Uninstalling requires extra steps, upgrading is basically impossible to do nicely. You can't roll back during a failure.
I harvest the "help" directory for our product with a "BeforeBuild" task of my wixproj.
I have a file called genComponents.targets which contains
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildThisFileDirectory)..\CommonBuild.props" Condition="$(_CommonBuildPropertyLoaded) != 'true'"/>
<PropertyGroup>
<HeatEXE>$(WixToolPath)Heat.exe</HeatEXE>
</PropertyGroup>
<Target Name="GenHelpDependsOn">
<PropertyGroup>
<HelpHeatArgs>dir "$(MSBuildThisFileDirectory)..\..\Help" -gg -cg BinHelp -dr BINHELP -template fragment -sreg -sfrag -srd -var var.dirHELP -o "$(MSBuildThisFileDirectory)Components\BinHelp.wxs"</HelpHeatArgs>
</PropertyGroup>
</Target>
<Target Name="GenBinHelp" DependsOnTargets="GenHelpDependsOn">
<Exec Command=""$(HeatEXE)" $(HelpHeatArgs)" Condition="!Exists('$(MSBuildThisFileDirectory)Components\BinHelp.wxs')"/>
</Target>
</Project>
And just use
<Target Name="BeforeBuild" DependsOnTargets="GenBinHelp" />
in my wixproj which will generate the wxs for the BinHelp component group for the directory with all the help files. There's a thousand or so help files for all the languages we support.
In the wixproj I add the wxs as a link and just make sure it is included in a feature as a ComponentGroupRef.
You can just include an <Exec> task in your beforebuild task with all the correct arguments I just use a second file because I have many heat tasks. There are lots of different arguments to heat and you can take a look at them with heat /? to see them.
Just run heat.exe on your js dir and see what it looks like.
In one project where I harvest all files with heat has 3836 files in it. Here's the process for the build. I grab the zip file of built binaries and other files from a network location and unzip all the file contents into a folder that I called ZipFolder.
In my wixproj I put a heat call in the before build target
<Target Name="BeforeBuild" >
<Exec Command=""$(WixToolPath)Heat.exe" dir "$(MSBuildThisFileDirectory)..\Binaries\ZipFolder" -ag -cg SDK -dr INSTALLDIR -suid -sreg -sfrag -srd -var var.ZipFolderDir -o "$(MSBuildThisFileDirectory)..\src\InstallerSDK\Components\SDKFiles.wxs"" Condition="!Exists('$(MSBuildThisFileDirectory)..\src\InstallerSDK\Components\SDKFiles.wxs')" />
</Target>
and in my wixproj I add an existing file SDKFiles.wxs as a link (small arrow on Add button shows drop down with "as link")
I'm using a few cmd line switches that you don't have defined in your heat call which I use so that I can reference the generated file's components properly. Firstly I use -var var.ZipFolderDir and this makes the source of your files equal to $(var.ZipFolderDir)\rest\of\path.dll. And you can just define this variable in your defineconstants (one for each configuration):
<DefineConstants>Debug;ZipFolderDir=$(MSBuildThisFileDirectory)..\Binaries\ZipFolder\;</DefineConstants>
<DefineConstants>ZipFolderDir=$(MSBuildThisFileDirectory)..\Binaries\ZipFolder\;</DefineConstants>
The other difference is also using -dr INSTALLFOLDER which will set the top level Directory to be INSTALLFOLDER which is defined by your INSTALLFOLDER directory in the product.wxs.
Finally there is -cg SDK defining the name of the component group which holds all the files harvested by heat. Here is where we tie in to the main product.wxs with a ComponentGroupRef
<Feature Id="ProductFeature" Title="SomeInstaller" Level="1">
<ComponentGroupRef Id="SDK" />
<ComponentGroupRef Id="ERMPanel.Binaries" />
<ComponentRef Id="comp_5D704CE7_9E55_4FC5_8CB2_6BA4612D6D35" />
<ComponentRef Id="comp_C9901889_BAD5_4B2C_9407_EAF967B1526C" />
<ComponentRef Id="comp_03332461_4D6C_4BB5_90D1_4C4D896D7775" />
<ComponentRef Id="comp_3AE770A3_904C_4458_81BD_300F195A4250" />
<ComponentRef Id="comp_dir_8F9BAB58_4415_4353_BE9E_36C8F7EEF78A" />
</Feature>
And you can remove your ProductComponents group at the bottom of the product.wxs
I've never used the <HarvestProject> but I do know wix has Harvest targets already defined but I never spent the time to figure out how to use them. I've also never used heat on a project either so I can't really help there. All my installer projects are built as their own separate projects due to the build process we use. Generally they grab a zip of binaries and unzip to a Binaries folder then build the installers calling heat on some folders.

wix installer / Create web-site and assign the new or exisiting web app pool

i try create a new web-site using wix installation. it's ok there is no problem but i cannot assign a new or existing web app pool to new web-site. iis:website tag does not contains WebAppPool attribute. How can i assign web app pool to web-site. You can see my code bellow.
thanks for helping.
<Component Id="WEB_SITE_CONFIGURE_COMPONENT" Guid="{35087032-D049-48C8-BCAD-1FEFD0C06A25}" NeverOverwrite="yes" Shared="yes" Permanent="yes" Transitive="yes">
<Condition><![CDATA[WEBSITE_INSTALLTYPE<>2]]></Condition>
<CreateFolder Directory="WEBSITE_FOLDER"/>
<iis:WebSite Id="WEB_SITE" Description="[WEBSITE_NAME]" SiteId="*" Directory="WEBSITE_FOLDER" ConfigureIfExists="yes" AutoStart="yes" StartOnInstall="yes">
<iis:WebAddress Id="AllUnassigned" Port="[WEBSITE_PORT]" />
</iis:WebSite>
<RegistryValue Root="HKLM" Key="$(var.DefaultRegistryKey)" Name="ConfigSite" Value="1" Type="string"></RegistryValue>
</Component>
<Component Id="WEBAPP_POOL_CONFIGURE_COMPONENT" Guid="{316738A6-26A2-4C14-9AB9-B2066E3FA288}" KeyPath="yes" Permanent="yes" Transitive="yes">
<Condition><![CDATA[(WEBSITE_INSTALLTYPE=0) OR (USE_CUSTOM_WEBSITE_FOLDER=1)]]></Condition>
<iis:WebAppPool Id="APP_POOL" Name="[WEBAPP_POOL_NAME]" ManagedPipelineMode="Classic" ManagedRuntimeVersion="v4.0"/>
<RegistryValue Root="HKLM" Key="$(var.DefaultRegistryKey)" Name="ConfigPool" Value="1" Type="string"></RegistryValue>
</Component>
<Component Id="WEPAPP_CONFIGURE_COMPONENT" Guid="{F95B024E-B6B6-4E6C-AC35-9B1086FC3521}" Transitive="yes">
<Condition><![CDATA[(WEBSITE_INSTALLTYPE<>2) AND ((WEBSITE_INSTALLTYPE=0) OR (USE_CUSTOM_WEBSITE_FOLDER=1))]]></Condition>
<iis:WebVirtualDir Id="VIRTUAL_DIR" Alias="[WEB_APP_NAME]" Directory="WWW_FOLDER" WebSite="WEB_SITE">
<iis:WebApplication Id="WEB_APP" Name="[WEB_APP_NAME]" WebAppPool="APP_POOL"/>
</iis:WebVirtualDir>
<RegistryValue Root="HKLM" Key="$(var.DefaultRegistryKey)" Name="ConfigVirtualDir" Value="1" Type="string"></RegistryValue>
</Component>
With the help of the following articles I have come up with a working installer in which a new AppPool can be created or an existing AppPool can be selected.
Creating a Web Application Installer with WIX 3.5 and Visual Studio 2010–Part 1
Web Application Installer in WiX
WiX and DTF: Using a Custom Action to list available web sites on IIS
Installing a Web Application to an Existing IIS Website using Wix3
In short:
Create a Website element in your Product element:
<Product>
<iis:WebSite Id="SelectedWebSite" Description="[WEBSITE_DESCRIPTION]" Directory="INSTALLFOLDER" SiteId="[WEBSITE_ID]">
<iis:WebAddress Id="AllUnassigned" Port="80" />
</iis:WebSite>
</Product>
Create an Include WebSites.wxi with the following content:
<?xml version="1.0" encoding="utf-8"?>
<Include>
<Property Id="WEBSITE_DESCRIPTION">
<RegistrySearch Id="WebSiteDescription" Name="WebSiteDescription" Root="HKLM" Key="SOFTWARE\!(loc.CompanyName)\[ProductName]\Install" Type="raw" />
</Property>
<Property Id="WEBSITE_ID">
<RegistrySearch Id="WebSiteID" Name="WebSiteID" Root="HKLM" Key="SOFTWARE\!(loc.CompanyName)\[ProductName]\Install" Type="raw" />
</Property>
<Property Id="WEBSITE_PATH">
<RegistrySearch Id="WebSitePath" Name="WebSitePath" Root="HKLM" Key="SOFTWARE\!(loc.CompanyName)\[ProductName]\Install" Type="raw" />
</Property>
<Property Id="WEBSITE_VD">
<RegistrySearch Id="WebSiteVD" Name="WebSiteVD" Root="HKLM" Key="SOFTWARE\!(loc.CompanyName)\[ProductName]\Install" Type="raw" />
</Property>
<CustomTable Id="AvailableWebSites">
<Column Id="WebSiteID" Category="Identifier" PrimaryKey="yes" Type="int" Width="4"/>
<Column Id="WebSiteDescription" Category="Text" Type="string" PrimaryKey="no"/>
<Column Id="WebSitePath" Category="Text" Type="string" PrimaryKey="no" Nullable="yes"/>
<Row>
<Data Column="WebSiteID">0</Data>
<Data Column="WebSiteDescription">Dummy</Data>
<Data Column="WebSitePath"></Data>
</Row>
</CustomTable>
</Include>
Create the CustomAction described here.
Create a wxs file with your AppPool:
<?xml version="1.0" encoding="UTF-8"?>
<Wix
xmlns="http://schemas.microsoft.com/wix/2006/wi"
xmlns:util="http://schemas.microsoft.com/wix/UtilExtension"
xmlns:iis="http://schemas.microsoft.com/wix/IIsExtension">
<Fragment>
<Component Id="WebVirtualDirComponent" Guid="PUT-GUID-HERE" Directory="INSTALLFOLDER" KeyPath="yes">
<iis:WebAppPool
Id="YourAppPoolName"
Name="[VD][WEBSITE_ID]"
ManagedRuntimeVersion="v4.0"
IdleTimeout="0"
RecycleMinutes="0"
ManagedPipelineMode="integrated"/>
<iis:WebVirtualDir Id="VDir" Alias="[VD]" Directory="INSTALLFOLDER" WebSite="SelectedWebSite">
<iis:WebApplication Id="NotizBrowserWebApp" WebAppPool="YourAppPoolName" Name="[VD][WEBSITE_ID]" />
<iis:WebDirProperties Id="NotizBrowserProps" AnonymousAccess="no" WindowsAuthentication="yes" DefaultDocuments="-" Execute="yes" Script="yes" Read="yes"/>
</iis:WebVirtualDir>
</Component>
</Fragment>
</Wix>
Late answer, but hopefully someone will be benefited with this.
You don't need a CustomAction to make this work.
It is simple like this:
<Component Id="WebSite" Guid="PUT-YOUR-GUID-HERE">
<CreateFolder/>
<iis:WebSite Id="WebSite" Directory="WebSiteRoot" Description="[WEBSITEDESCRIPTION]" >
<iis:WebApplication Id="WebSiteApplication" Name="[WEBSITEDESCRIPTION]" WebAppPool="MyAppPool" />
</iis:WebSite>
<iis:WebAppPool Id="MyAppPool" Name="[APPPOOLNAME]" ManagedRuntimeVersion="v4.0"/>
</Component>
You need to update the "Internal" WebApplication of the WebSite.
You don't need to have the "WebSite Description" and "WebApplication Name" equal, but that will help you to understand what is going on.

how to fix warning ICE39: Admin Image flag set in SummaryInfo stream

I am creating an installer using Wix in visual studios 2012. Below is my code for the product.wxs. I am receiving a "warning ICE39: 'Admin Image' flag set in SummaryInfo stream. Should be set only for Admin packages." I have changed admin image from yes to no and rebuilt, it removes the warning but i am still unable to install on a computer that has local admin privileges, and is also a domain admin. However, i can install it on my machine, and im not a domain admin,
I would upload the image but not enough rep yet. here is an image link.
http://i656.photobucket.com/albums/uu290/chrizbahr/warning_zps12f388b2.png
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<?define ProductName="CHC Pedometer Sync"?>
<?define ProductVersion="1.0.0"?>
<?define ProductGUID="{6D234D2C-5F74-42A8-A9DA-14D684B2EAFC}"?>
<?define ProductUpgradeCode="{DDDD43E0-DB34-4AD6-BF54-F6B12509E84F}"?>
<?define Manufacturer="CHC Wellness"?>
<Product Id="$(var.ProductGUID)"
Name="$(var.ProductName)"
Language="1033"
Version="$(var.ProductVersion)"
Manufacturer="$(var.Manufacturer)"
UpgradeCode="$(var.ProductUpgradeCode)">
<Package Id="*"
Description="CHC Pedometer Sync Installer"
Keywords="Installer"
Manufacturer="$(var.Manufacturer)"
SummaryCodepage="1252"
InstallerVersion="200"
Compressed="yes"
InstallScope="perMachine"
AdminImage="yes"
InstallPrivileges="limited" />
<MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
<MediaTemplate EmbedCab="yes"/>
<!--DIRECTORY STRUCTURE-->
<Directory Id="TARGETDIR" Name="SourceDir">
<!--PROGRAM FILES-->
<Directory Id="ProgramFilesFolder" Name="PFiles">
<Directory Id="CHCWellness" Name="CHC Wellness">
<Directory Id="INSTALLDIR" Name="$(var.ProductName)" />
</Directory>
</Directory>
<!--DESKTOP-->
<Directory Id="DesktopFolder" Name="Desktop"/>
<!--START MENU-->
<Directory Id="ProgramMenuFolder" Name="Programs">
<Directory Id="ProgramMenuDir" Name="$(var.Manufacturer)" />
</Directory>
</Directory>
<DirectoryRef Id="INSTALLDIR">
<Component Id="MainExecutable" Guid="{FB74004F-F250-4B3C-B38C-D96D5657A27A}">
<File Id="File_MainExecutable" Source="..\PedometerSync\bin\Release\PedometerSync.exe" Vital="yes" DiskId="1" KeyPath="yes">
<Shortcut Id="MainExeShortcutDesktop"
Name="$(var.ProductName)"
Directory="DesktopFolder"
Description="$(var.ProductName)"
WorkingDirectory="INSTALLDIR"
Advertise="yes"
Icon="icon.ico" />
</File>
</Component>
<Component Id="InterfaceExe" Guid="{68C78DE2-BEBB-41D7-B9F6-313BCFC88F68}">
<File Id="PedometerInterfaceEXE" Source="..\PedometerSync\bin\Release\PedometerInterface.exe" Vital="yes" DiskId="1" KeyPath="yes" />
</Component>
<Component Id="EXEConfig" Guid="{8D9F2744-C1E4-45E1-88E7-C3427200767E}">
<File Id="File_ExeConfigFile" Source="..\PedometerSync\bin\Release\PedometerSync.exe.config" Vital="yes" DiskId="1" KeyPath="yes" />
</Component>
<Component Id="Newtonsoft" Guid="{09343B58-A247-4AA9-9A32-A6CB1BD9CC2F}">
<File Id="file_newtonsoft.json.dll" Source="..\PedometerSync\bin\Release\Newtonsoft.Json.dll" Vital="yes" DiskId="1" KeyPath="yes" />
</Component>
</DirectoryRef>
<!--SHORTCUTS-->
<DirectoryRef Id="ProgramMenuDir">
<Component Id="StartMenuShortcut" Guid="{E02282A4-0907-4EC6-A5B7-623E50B4E642}">
<Shortcut Id="MainExeShortcut"
Name="$(var.ProductName)"
Description="$(var.ProductName)"
Target="[INSTALLDIR]PedometerSync.exe"
Icon="icon.ico"/>
<RemoveFolder Id="RemoveStartMenuShortcutDir" On="uninstall"/>
<RegistryValue Root="HKCU" Key="Software\$(var.Manufacturer)\$(var.ProductName)" Name="installed" Type="integer" Value="1" KeyPath="yes" />
</Component>
</DirectoryRef>
<!--FEATURES LIST-->
<Feature Id="Standard" Level="1">
<ComponentRef Id="MainExecutable"/>
<ComponentRef Id="InterfaceExe"/>
<ComponentRef Id="EXEConfig"/>
<ComponentRef Id="Newtonsoft"/>
<ComponentRef Id="StartMenuShortcut"/>
</Feature>
<!--ADD UI ELEMENTS-->
<Property Id="WIXUI_INSTALLDIR" Value="INSTALLDIR" />
<UIRef Id="WixUI_InstallDirCustom" />
<UIRef Id="WixUI_ErrorProgressText" />
<!--CUSTOM IMAGES-->
<WixVariable Id="WixUIBannerBmp" Value="banner.bmp" />
<WixVariable Id="WixUIDialogBmp" Value="dialog.bmp" />
<!--ICONS-->
<Icon Id="icon.ico" SourceFile="icon.ico" />
</Product>
</Wix>
Remove the Admin attribute. This attribute doesn't refer to needing admin rights to install a package, it refers to whether the MSI is a normal Installation or an Administrative Installation.
For more information, see the help topics:
Administrative Installation (Windows)
Word Count Summary property (Windows) (Notice the definition of bit 2 and bit 3 these correlate to the AdminImage and InstallPrivileges attributes respectively)

How to add condition in component?

My requirement is to add below mentioned scenarios in same installer.
Create a virtual directory under default web site if IIS version is 5.1
Create a new web site if IIS version is equal to or greater than 6.
I added code as given below but it is not working.
<DirectoryRef Id="ServDir">
<Directory Id="ServerWebDIR" Name="$(var.Manufacturer_WWW_LONG_DIRNAME)">
<Component Id="$(var.ServerWeb_Id)" Guid="$(var.ServerWeb_Component_GUID)">
<File Id="FLSW_admin.html" DiskId="1" Name="admin.html" Source="$(var.SERVER_wwwDir)admin.html" />
<RemoveFolder Id="FLSW_admin.html On="uninstall" />
</Component>
</Directory>
<Component Id="TestWebVirtualDirComponent" Guid="{F509D5DC-3F13-4AAF-974E-0D7EF82EE4B2}">
<Condition>IISMAJORVERSION = "#5"</Condition>
<CreateFolder/>
<iis:WebVirtualDir Id="WebDir" Alias="$(var.VirtualDirAlias)" Directory="ServerWebDIR" WebSite="DefaultWebSite" DirProperties="WebDirProperty">
<iis:WebApplication Id="TestWebApplication" Name="$(var.VirtualDirAlias)"/>
</iis:WebVirtualDir>
</Component>
<Component Id="WebSite" Guid="{F509D5DC-3F13-4AAF-974E-0D7EF82EE4B3}">
<Condition>IISMAJORVERSION >= "#6"</Condition>
<CreateFolder />
<iis:WebSite Id="WebSiteFolder" Description="$(var.EnterpriseWebSiteDescription)" Directory='ServerWebDIR'>
<iis:WebAddress Id="AllUnassigned" Port="80" />
</iis:WebSite>
</Component>
</DirectoryRef>
<iis:WebDirProperties Id="WebDirProperty" Execute="yes" Script="yes" Read="yes" />
<iis:WebDirProperties Id="WebDirPropertyForbidExecution" Execute="no" Script="yes" Read="yes" />
<iis:WebSite Id="DefaultWebSite" Description="Default Web Site" >
<iis:WebAddress Id="AllUnassigned1" Port="80" />
</iis:WebSite>
What is the problem with my code. Please anyone suggests that how to achieve my requirement in same installer?

Resources