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.
Related
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.
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)
I am new to wix and am havaingsome issues using the copyfile component in wix. Please can you loke at the code below and advise. Many Thanks in advanced.
I have 3 features, 3 componentgroups & 3 components as described below with the respective directoryRef
<Feature Id = "F1" Title "T1" Level ="1">
<ComponetGroupRef Id="CG1" />
<Condition Level="1">
<![CDATA[ComputerName="S1"]
</Condition>
</Feature>
<Feature Id = "F1" Title "T1" Level ="1">
<ComponetGroupRef Id="CG2" />
<Condition Level="1">
<![CDATA[ComputerName="S2"]
</Condition>
</Feature>
<Feature Id = "F1" Title "T1" Level ="1">
<ComponetGroupRef Id="CG3" />
<Condition Level="1">
<![CDATA[ComputerName="S3"]
</Condition>
</Feature>
<ComponentGroup id="CG1">
<ComponentRef id="c1" />
</ComponentGroup>
<ComponentGroup id="CG2">
<ComponentRef id="c2" />
</ComponentGroup>
<ComponentGroup id="CG3">
<ComponentRef id="c1" />
<ComponentRef id="c2" />
</ComponentGroup>
<DirectoryRef Id"ApplicationDirectory">
<Component Id="C1" Guid="xyz">
<File Id="F1"KeyPath="yes" Source="Some Source Location">
<CopyFile Id="CF1" DestinationDirectory="Dest1" />
</File>
</Component>
<Component Id="C2" Guid="abc">
<File Id="F2"KeyPath="yes" Source="Some Source Location">
<CopyFile Id="CF2" DestinationDirectory="Dest2" />
</File>
</Component>
</DirectoryRef>
so basically if I am running the wix msi on server S1 only File F1 should be copied, when I am running on server S2 only File F2 should be copied and when I am running on Server S3, Files F1 & F2 both should be copied.
The issue I am having is that all the files are being copied irrespictive or server name match.
Can you please advise if I am being foolish.
Thanks,
Janak
Wix is not for copy.
I defined a different wix template project for the work I wanted to do. So instead of copy from destination to another location. I changed the project implementation so that it copies from source to a different destination.
I have installed Cruise Control 1.5 on my machine and trying to configure the automated build. Everything is working fine. Application is building, i receive an email but I don't see the FXCop result embedded in the Build Email. What am i missing?
ccnet.config file
<cruisecontrol xmlns:cb="urn:ccnet.config.builder">
<project name="SampleProject">
<webURL>http://localhost/ccnet</webURL>
<workingDirectory>E:\\NewProject\\DevBuilds</workingDirectory>
<artifactDirectory>E:\\NewProject\\DevBuilds\Artifacts</artifactDirectory>
<modificationDelaySeconds>600</modificationDelaySeconds>
<category>Dev Build</category>
<sourcecontrol type="svn">
<trunkUrl>https://mycompany.com/svn/trunk/MyApplication</trunkUrl>
<workingDirectory>E:\\NewProject\\DevBuilds\SourceCode</workingDirectory>
<autoGetSource>false</autoGetSource>
<executable>C:\Program Files\Subversion\bin\svn.exe</executable>
<username>username</username>
<password>password</password>
</sourcecontrol>
<initialState>Started</initialState>
<startupMode>UseInitialState</startupMode>
<triggers>
<intervalTrigger seconds="3600" buildCondition="IfModificationExists" />
</triggers>
<state type="state" directory="E:\\NewProject\\DevBuilds" />
<labeller type="iterationlabeller">
<prefix>1.0</prefix>
<duration>1</duration>
<releaseStartDate>2012/04/11</releaseStartDate>
<separator>.</separator>
</labeller>
<tasks>
<nant>
<executable>E:\NewProject\Installables\nant\bin\nant.exe</executable>
<baseDirectory>E:\\NewProject\\Build Files</baseDirectory>
<buildFile>Build.xml</buildFile>
<targetList>
<target>Run</target>
</targetList>
<buildTimeoutSeconds>5000</buildTimeoutSeconds>
</nant>
</tasks>
<publishers>
<merge>
<files>
<file>E:\NewProject\DevBuilds\FxCopOutput\FxCop-results.xml</file>
</files>
</merge>
<xmllogger logDir="E:\\NewProject\\DevBuilds\Artifacts\\buildlogs" />
<email from="Checkins#symphonysv.com" mailhost="smtp.gmail.com" includeDetails="true" useSSL="false">
<users>
<user name="dev1" group="buildmaster" address="myname#gmail.com"/>
</users>
<groups>
<group name="buildmaster">
<notifications>
<notificationType>Always</notificationType>
</notifications>
</group>
</groups>
</email>
</publishers>
</project>
</cruisecontrol>
Build.xml
<?xml version="1.0"?>
<project name="Test" default="Run" basedir=".">
<property name="BuildNumber" value="1.0.0.0"/>
<property name="SourceControlURL" value="https://mycompany.com/svn/trunk/MyApplication/"/>
<property name="BuildFile" value=".\Build.xml"/>
<property name="TagBuild" value="false"/>
<property name="BuildType" value="Release"/>
<property name="BuildTargetDir" value="E:\NewProject\DevBuilds\Executables"/>
<property name="BuildWorkDir" value="E:\NewProject\DevBuilds\SourceCode"/>
<property name="MSBUILD" value="C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319"/>
<property name="FxCopOutPutDirectory" value="E:\NewProject\DevBuilds\FxCopOutput" />
<property name="FxCopInputDirectory" value="E:\NewProject\DevBuilds" />
<target name="Run" description="Starting ThinkPets Build">
<call target="GetLatestCode"/>
<call target="BuildCode"/>
<call target="BuildASPWebSite"/>
<call target="runFxCop"/>
</target>
<target name="GetLatestCode">
<echo message="Updating Code From SVN to ${BuildWorkDir}"/>
<exec program="svn.exe">
<arg line="checkout ${SourceControlURL} ${BuildWorkDir} -q"/>
</exec>
</target>
<target name="BuildCode">
<echo message="Building VS10 Projects Web" />
<exec program="${MSBUILD}\msbuild.exe" failonerror="true">
<arg line=" "${BuildWorkDir}\Application.sln" /t:Rebuild /p:Configuration=Release /V:q"/>
</exec>
</target>
<target name="BuildASPWebSite">
<echo message="Building ASP Web Site" />
<exec program="${MSBUILD}\aspnet_compiler.exe" failonerror="true">
<arg line=" -v / -p "${BuildWorkDir}\MyDir" -f -c "${BuildTargetDir}" "/>
</exec>
</target>
<target name="runFxCop" depends="BuildCode">
<exec program="C:\Program Files\Microsoft FxCop 1.36\FxCopCmd.exe" failonerror="false">
<arg line="/p:${FxCopInputDirectory}\SampleProject.FxCop /o:${FxCopOutPutDirectory}\FxCop-results.xml"/>
</exec>
</target>
</project>
There are a few points you missed:
You need to add <includeDetails>true</includeDetails> to your e-mail publisher block. This will give you HTML e-mails.
In order to transform your XML build results into HTML you need to add an <xslFiles> section to your e-mail publisher block. The elements of this block point to XSL transformation files in [CCNET_INSTALL_DIR]\server\xsl.
So for including the FxCop summary just as appears in CCNET webdasboard this is your e-mail publisher block:
<email from="Checkins#symphonysv.com" mailhost="smtp.gmail.com" includeDetails="true" useSSL="false">
<users>
<user name="dev1" group="buildmaster" address="myname#gmail.com"/>
</users>
<groups>
<group name="buildmaster">
<notifications>
<notificationType>Always</notificationType>
</notifications>
</group>
</groups>
<includeDetails>true</includeDetails>
<xslFiles>
<file>xsl\fxcop-summary_1_36.xsl</file>
</xslFiles>
</email>
Thanks Chairman for your valuable time. I think my mistake was that I did not host the "ccnet" application on my machine which resulted in not able to find the xsls for the publishers. When I used the same settings and config file on the Server machine with "ccnet" application hosted, I was able to see the FxCop summary in the email. Please correct my understanding if wrong.
I have installed uppercut integrated cc.net such a way that i didnt make any change in webdashboard,
This is my cc.net config code,
-->
-->
<!-- PROJECT STRUCTURE -->
<cb:define name="WindowsFormsApplication1">
<project name="$(projectName)">
<workingDirectory>$(working_directory)\$(projectName)</workingDirectory>
<artifactDirectory>$(drop_directory)\$(projectName)</artifactDirectory>
<category>$(projectName)</category>
<queuePriority>$(queuePriority)</queuePriority>
<triggers>
<intervalTrigger name="continuous" seconds="60" buildCondition="IfModificationExists" />
</triggers>
<sourcecontrol type="svn">
<executable>c:\program files\subversion\bin\svn.exe</executable>
<!--<trunkUrl>http://192.168.1.8/trainingrepos/deepasundari/WindowsFormsApplication1</trunkUrl>-->
<trunkUrl>$(svnPath)</trunkUrl>
<workingDirectory>$(working_directory)\$(projectName)</workingDirectory>
</sourcecontrol>
<tasks>
<msbuild>
<executable>C:\WINDOWS\Microsoft.NET\Framework\v3.5\MSBuild.exe</executable>
<workingDirectory>$(working_directory)\$(projectName)</workingDirectory>
<projectFile>WindowsFormsApplication1.sln</projectFile>
<timeout>600</timeout>
<buildArgs> /noconsolelogger /p:configuration=Debug </buildArgs>
<!--<buildArgs>/noconsolelogger /p:OutputPath=$(drop_directory)\$(projectName)\sample </buildArgs>-->
<logger>ThoughtWorks.CruiseControl.MsBuild.XmlLogger,C:\Program Files\CruiseControl.NET\server\ThoughtWorks.CruiseControl.MsBuild.dll</logger>
</msbuild>
<!--<labeller type="svnRevisionLabeller">
<prefix>Test-</prefix>
<major>7</major>
<minor>11</minor>
<url>$svnpath</url>
<username>deepasundari</username>
<password>deepasundari</password>
</labeller>-->
<exec>
<executable>$(working_directory)\$(projectName)\build.bat</executable>
</exec>
</tasks>
<publishers>
<!--<buildpublisher>
--><!--<sourceDir>C:\myprojects\project1</sourceDir>--><!--
<publishDir>$(working_directory)\$(projectName)</publishDir>
</buildpublisher>-->
<merge>
<files>
<file>$(working_directory)\$(projectName)\build_output\build_artifacts\*.xml</file>
<file>$(working_directory)\$(projectName)\build_output\build_artifacts\mbunit\*-results.xml</file>
<file>$(working_directory)\$(projectName)\build_output\build_artifacts\nunit\*-results.xml</file>
<file>$(working_directory)\$(projectName)\build_output\build_artifacts\ncover\*-results.xml</file>
<file>$(working_directory)\$(projectName)\build_output\build_artifacts\ndepend\*.xml</file>
</files>
</merge>
<!--<email from="buildserver#somewhere.com" mailhost="smtp.somewhere.com" includeDetails="TRUE">
<users>
<user name="YOUR NAME" group="BuildNotice" address="yourEmail#somewhere.com" />
</users>
<groups>
<group name="BuildNotice" notification="change" />
</groups>
</email>-->
<xmllogger/>
<statistics>
<statisticList>
<firstMatch name="Svn Revision" xpath="//modifications/modification/changeNumber" />
<firstMatch name="ILInstructions" xpath="//ApplicationMetrics/#NILInstruction" />
<firstMatch name="LinesOfCode" xpath="//ApplicationMetrics/#NbLinesOfCode" />
<firstMatch name="LinesOfComment" xpath="//ApplicationMetrics/#NbLinesOfComment" />
</statisticList>
</statistics>
<modificationHistory onlyLogWhenChangesFound="true" />
<rss/>
</publishers>
</project>
</cb:define>
<cb:WindowsFormsApplication1 projectname="WindowsFormsApplication1" queuepriority="1" svnpath="http://192.168.1.8/trainingrepos/deepasundari/WindowsFormsApplication1" />
this code is updating rss and report xml files, but i could not get the build folder in the code_drop..
could anyone help me with this problem??
It looks like you have followed the sample almost perfectly. http://uppercut.googlecode.com/svn/trunk/docs/Samples/CC.NET/server/ccnet.config
What you should see in the code_drop folder on the build server is a folder b##-r## for build and revision per each build.
Most of this is talked about in here: http://uppercut.googlecode.com/svn/trunk/docs/IntegrateUppercuTWithCruiseControl.NET.doc