Specific cordova hooks in config.xml per platform - node.js

I was trying to use to run specific nodejs scripts per pratform.
In the docs it says it is possible set a hook per platform:
https://cordova.apache.org/docs/en/edge/guide_appdev_hooks_index.md.html
If i put the hooks in config.xml outsite of the platforms tags, the scripts will be called:
<hook type="before_platform_add" src="HookInstallPluginsWP8.js" />
<hook type="before_platform_add" src="HookInstallPluginsIOS.js" />
But if I put it inside a tag it does not run:
<platform name="wp8">
<preference name="fullscreen" value="true"/>
<hook type="before_platform_add" src="HookInstallPluginsWP8.js" />
</platform>
<platform name="ios">
<preference name="fullscreen" value="true"/>
<hook type="before_platform_add" src="HookInstallPluginsIOS.js" />
</platform>
What I'm doing wrong?

This doesn't seem to be supported until Cordova 5.x. Are you sure you are running the latest Cordova?
npm install -g cordova

I think I found the reason why this was happening.
Today I tried to add <icons> and <splash> images to my project and I faced the same situation. The icons and splash were not added if inside a platform tag.
In my case this was happening because inside a <platform> tag, it only could exist one type of tag.
For example:
<platform name="android">
<preference name="fullscreen" value="true"/>
<hook type="before_platform_add" src="HookInstallPluginsAndroid.js" />
<icon src="res/icons/android/icon-36-ldpi.png density="ldpi" />
</platform>
In this case the hook and the icon will be ignored.
I have to add different <platform> nodes:
<platform name="android">
<preference name="fullscreen" value="true"/>
</platform>
<platform name="android">
<icon src="res/icons/android/icon-36-ldpi.png density="ldpi" />
</platform>
<platform name="android">
<hook type="before_platform_add" src="HookInstallPluginsAndroid.js" />
</platform>
Is this a documented case? I did not found anything on cordova docs... maybe it's just a bogus situation?

Related

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.

Haxe program to hide console

I am trying to hide the console when running the Haxe application.
I am using FlashDevelop to compile Haxe into hxcpp, and this is my project.xml
<?xml version="1.0" encoding="utf-8"?>
<project>
<!-- metadata, make sure 'package' is at least 3 segments (ie. com.mycompany.myproject) -->
<meta title="haxeGame" package="haxeGame" version="1.0.0" company="xiggie" />
<!-- output -->
<app main="Main" file="haxeGame" path="bin" />
<window width="800" height="480" fps="60" background="0x000000" orientation="landscape" resizable="false" borderless="true" />
<window vsync="true" antialiasing="6" />
<!-- classpath, haxe libs -->
<classpath name="src" />
<haxelib name="openfl" />
<haxelib name="actuate" />
<!-- assets -->
<icon path="assets/texture.jpg" />
<assets path="assets" rename="assets" />
<!-- optimize output
<haxeflag name="-dce full" /> -->
<!-- Windows app: hide console -->
<setenv name="no_console" value="1" />
<flag value="subsystem:windows" />
</project>
I have tried all of these:
<haxeflag name="-D no_console" />
<haxedef name="no_console" />
<setenv name="no_console" value="1" />
Is it actually possible to remove the console from the release app?
The console should be hidden by default. To make it appear one needs to add
<setenv name="SHOW_CONSOLE" />
However, when using mingw instead of msvc as compiler, the toolchain configuration that comes with hxcpp currently does not pass the flag to the linker that avoids the creation of a console window.
To work around this, search for the mingw-toolchain.xml in your haxe installation and add the -mwindows flag to the linker configuration.
I created a pull request for this https://github.com/HaxeFoundation/hxcpp/pull/286

Can't get devices language in phonegap

I'm doing this exact example from the phonegap docs.
<!DOCTYPE HTML>
<html>
<head>
<title>getPreferredLanguage Example</title>
<script type="text/javascript" charset="utf-8" src="cordova.js"></script>
<script type="text/javascript" charset="utf-8">
function checkLanguage() {
navigator.globalization.getPreferredLanguage(
function (language) {alert('language: ' + language.value + '\n');},
function () {alert('Error getting language\n');}
);
}
</script>
</head>
<body>
<button onclick="checkLanguage()">Click for language</button>
</body>
</html>
When I click the button I want it to return the language I'm using on my phone.
It works good if I run it through the PhoneGap app, while connected to the local server on my computer (phonegap serve) however it won't work after making the .apk and installing it on my phone. What am I missing?
edit: here's the config.xml
http://pastebin.com/t6fx3jRD
<?xml version='1.0' encoding='utf-8'?>
<widget id="com.phonegap.helloworld" version="1.0.0"
xmlns="http://www.w3.org/ns/widgets"
xmlns:gap="http://phonegap.com/ns/1.0">
<name>hi bi</name>
<description>
sample stuff
</description>
<author email="support#phonegap.com" href="http://phonegap.com">
PhoneGap Team
</author>
<content src="index.html" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<preference name="phonegap-version" value="3.3.0" />
<preference name="permissions" value="none" />
<preference name="orientation" value="default" />
<preference name="target-device" value="universal" />
<preference name="fullscreen" value="true" />
<preference name="webviewbounce" value="true" />
<preference name="prerendered-icon" value="true" />
<preference name="stay-in-webview" value="false" />
<preference name="ios-statusbarstyle" value="black-opaque" />
<preference name="detect-data-types" value="true" />
<preference name="exit-on-suspend" value="false" />
<preference name="show-splash-screen-spinner" value="true" />
<preference name="auto-hide-splash-screen" value="true" />
<preference name="android-installLocation" value="auto" />
<icon src="icon.png" />
</widget>
I don't see any obvious problems, but there are five things that should be resolved.
you need to post your config.xml to this forum. If you delete that pastebin file, others will not be able to benefit from this. (If we can get it to work.)
you are using the generic file, which is not a bad thing, except the large file makes it more difficult to spot a problem.
you did NOT use <preference name="phonegap-version" value="X.X.X" />, which is not required. But since you do not, then by default you get the latest version (the bleeding edge) of the phonegap. (This might get you leading edge bugs which would be difficult to debug -- without asking for lots of help.)
Since you are using the latest version of Phonegap, and not 3.3.0, then you should reference leading edge - which does not have an full example.
Since you did NOT say what your target platform is, then perhaps you should look at the Bug List
Lastly, you might consider using an earlier version, say <preference name="phonegap-version" value="3.3.0" />, and try you build again. Oh and RTFM.
Best of Luck, Jesse

Conditional Include on Items in an Item Group

I want to copy files over to a server but before i do this i would like to include the latest msi file that i generate.
I noticed that the ItemGroup and Item have a Condition attribute but i do not know how to utilize this to include the latest file.
So far this is my setup:
<Target Name="AfterBuild">
<ItemGroup>
<Installers Include="\\SERVERNAME\BuildOutput\ProductStream\**\Installers\Customer\Installer.msi"/>
</ItemGroup>
<Message Text="FirstItem: %(Installers.Filename)" />
<Message Text="FirstItem: %(Installers.FullPath)" />
The output of this are two files:
e.g
\\Servername\BuildOutput\ProductStream\Installers\ProductStreamV2.1.1202.1402\Installer.msi
\\Servername\BuildOutput\ProductStream\Installers\ProductStreamV2.1.1405.1301\Installer.msi
I want to include the 2.1.1405.1301 build in the Item as this is the latest one.
I would appreciate if someone would assist me because i cannot find how to go about doing this from the MSDN blogs.
Thanks,
You could use a custom task for this purpose. It allows you to filter items any way you want. Here I used regular expressions to select the latest installer:
<Target Name="AfterBuild">
<ItemGroup>
<Installers Include="**\Installer.msi"/>
</ItemGroup>
<SelectLatestInstaller Installers="#(Installers)">
<Output TaskParameter="LatestInstaller" ItemName="LatestInstaller" />
</SelectLatestInstaller>
<Message Text="%(LatestInstaller.FullPath)" />
</Target>
<UsingTask TaskName="SelectLatestInstaller"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<Installers ParameterType="System.String[]" Required="true" />
<LatestInstaller ParameterType="System.String" Output="true" />
</ParameterGroup>
<Task>
<Reference Include="System.Linq" />
<Using Namespace="System" />
<Using Namespace="System.Linq" />
<Using Namespace="System.Text.RegularExpressions" />
<Code Type="Fragment" Language="cs">
<![CDATA[
LatestInstaller = Installers
.OrderByDescending(f => Regex.Match(f, #"\\ProductStreamV(?<version>(\d+.){0,3}\d+)\\").Groups["version"].Value)
.FirstOrDefault();
]]>
</Code>
</Task>
</UsingTask>

Wix RegistryKey Permission

I am attempting to install a registry key that should only be accessible by certain users. Every other part of the installer works (it installs a service and registers a component). Here is the fragment.
<Component Id="cmpXXX" Guid="{YYY}">
<RegistryKey Root="HKLM" Key="Software\ZZZ" Action="createAndRemoveOnUninstall">
<RegistryKey Key="Machine" Action="createAndRemoveOnUninstall">
<Permission User="Administrators" GenericAll="yes" />
<RegistryValue Type="string" Name="ID" Value="SecretID" />
<RegistryValue Type="string" Name="Key" Value="SecretKey" />
</RegistryKey>
</RegistryKey>
</Component>
When the installer is complete, all users can read the key (instead of just administrators). My command line to install is this:
msiexec /i installer.msi /l*v installlog.txt
The log says nothing about permissions.
When I open the database in Orca, the LockPermissions table shows the permission row and it looks fine.
What am I doing wrong?
It seemed to start working after I added the permission entry to each RegistryValue.
<Component Id="cmpXXX" Guid="{YYY}">
<RegistryKey Root="HKLM" Key="Software\ZZZ" Action="createAndRemoveOnUninstall">
<RegistryKey Key="Machine" Action="createAndRemoveOnUninstall">
<Permission User="Administrators" GenericAll="yes" />
<RegistryValue Type="string" Name="ID" Value="SecretID">
<Permission User="Administrators" GenericAll="yes" />
</RegistryValue>
<RegistryValue Type="string" Name="Key" Value="SecretKey">
<Permission User="Administrators" GenericAll="yes" />
</RegistryValue>
</RegistryKey>
</RegistryKey>
</Component>
But it has the side effect of locking down the entire Software\ZZZ key. Less than ideal, but I can work around that.
If you create values in multiple components, or you create intermediate keys (Software\XXX and Software\XXX\YYY) make sure that all the and have a child element.

Resources