I have a lot files to harvest in a per user install project in wix.
I used heat.exe to harvest the file, but each file in one component has its own keypath property, while my files will copy to "app data" so it has to use a registry key under HKCU as its KeyPath, so I have to change each item in the XML file.
Can it be done by heat.exe? I have thousands of files to harvest, it is terrible to fix it manually.
Use this xslt to customize KeyPath item for nodes that have child nodes.
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:msxsl="urn:schemas-microsoft-com:xslt"
exclude-result-prefixes="msxsl"
xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"
xmlns:my="my:my">
<xsl:output method="xml" indent="yes" />
<xsl:strip-space elements="*"/>
<xsl:template match="#*|node()">
<xsl:copy>
<xsl:apply-templates select="#*|node()"/>
</xsl:copy>
</xsl:template>
<xsl:template match='wix:Wix/wix:Fragment/wix:ComponentGroup/wix:Component'>
<xsl:copy>
<xsl:apply-templates select="#*"/>
<xsl:attribute name="KeyPath">
<xsl:text>no</xsl:text>
</xsl:attribute>
<xsl:apply-templates select="node()"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
derived from #KirillPolishchuk 's answer https://stackoverflow.com/a/8035049/483588
As far as I know, heat doesn't support this out-of-the-box. However, you can apply an XSL template to the heat output and tweak the final wxs file the way you'd like. See -t: switch of heat.exe for more details.
Related
XALANC-421 (omit-xml-declaration ignored) is supposed to be fixed in Xalan 1.11.0 according to the release notes at https://apache.github.io/xalan-c/releases.html. However, I still observe this issue until Xalan 1.12.0.
Sample files from Ch. 6 of Learning XSLT were used in my testing.
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:template match="eu">
<xsl:apply-templates select="member"/>
</xsl:template>
<xsl:template match="member">
<eu-members>
<xsl:apply-templates select="state[#founding]"/>
</eu-members>
</xsl:template>
<xsl:template match="state">
<xsl:copy>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Shortened version of input file
<?xml version="1.0" encoding="UTF-8"?>
<!-- European Union member states and candidate states -->
<eu>
<member>
<state>Austria</state>
<state founding="yes">Belgium</state>
<state>Denmark</state>
</member>
<candidate>
<state>Bulgaria</state>
<state>Cyprus</state>
</candidate>
</eu>
Output still has the xml declaration using xalan 1.11.0
<?xml version="1.0" encoding="UTF-8"?>
<eu-members xmlns:xml="http://www.w3.org/XML/1998/namespace">
<state>Belgium</state>
</eu-members>
Output using xalan 1.12.0
<eu-members>
<state>Belgium</state>
</eu-members>
Newbie to Wix in need of some help with patch making.
In my installer, it uses Heat.exe on an entire folder called "Assemblies" which contains a bunch of .dll files. I want to update one of these .dll files with one that has a higher version number (say from 1.1.0.0 to 4.0.1.0). The command for the heat is done before the installer is built and is below:
<HeatDirectory Directory="..\..\..\ProgressCode\Assemblies" OutputFile="$(ProjectDir)\Generated\Assemblies.wxs" PreprocessorVariable="var.AssembliesPath" DirectoryRefId="Assemblies" AutoGenerateGuids="true" Toolpath="$(WixToolPath)" ComponentGroupName="AssembliesComponentGenerated" SuppressFragments="true" SuppressRegistry="true" SuppressRootDirectory="true" Transforms="$(SolutionDir)\WixInstaller\RemoveAssembliesXml.xslt" />
These are also stored in the GAC but I have no idea how it does that.
The transform file (RemoveAssembliesXml.xslt) is below:
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:wi="http://schemas.microsoft.com/wix/2006/wi">
<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>
<xsl:strip-space elements="*"/>
<xsl:key name="compsToRemove"
match="wi:Component[(contains(wi:File/#Source,'Assemblies.xml'))]"
use="#Id"/>
<xsl:template match="#* | node()">
<xsl:copy>
<xsl:apply-templates select="#* | node()" />
</xsl:copy>
</xsl:template>
<xsl:template match="*[self::wi:Component or self::wi:ComponentRef] [key('compsToRemove',#Id)]" />
</xsl:stylesheet>
My patch file is pretty simple as I want it to pick up all the differences between the original and transformed msi.
<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">
<Patch
AllowRemoval="yes"
Manufacturer="Test"
DisplayName="Sample Patch"
Description="Small Update Patch"
Classification="Update"
>
<Media Id="5000" Cabinet="Patchy.cab">
<PatchBaseline Id="Patchy"/>
</Media>
</Patch>
</Wix>
It picks up the new files I want to add but not the changed .dll file. Is there anything specific I need to do to force it to find and update the .dll?
I am trying to process my .coveragexml file (after converting the .coverage file) that I get after using MSTest from the command line but Sonar Runner keeps failing as it tries to parse the file.
The errors consist of parsing errors such as an unexpected '?' as well as not being able to find the tag in the file.
I have tried a few ways to get the .coveragexml file: using the "vsinstr -coverage ..." and "start vsperfmon -coverage ..." commands (then running MSTest) from the command line, changing
the .testrunconfig file and indicating which dlls I want to get coverage for, and tried using "CodeCoverage.exe collect ...". The first two have given me success on getting code coverage data,
but I have had issues getting "CodeCoverage.exe collect ..." to collect results. Even though I can get collect code coverage results from the first two, the .coveragexml file that is
produced does not seem to be in the right format that SonarQube accepts, even though they indicate on their VB.NET plugin webpage that they support MSTest and VSTest XML code coverage files.
I have tried using VSTest and can get my .coveragexml files to be accepted by Sonarqube without any errors just fine. The problem is that the company I am interning for uses MSTest to run all
of their unit tests, so I need to get .coveragexml data from using MSTest.
Another thing I noticed was that when I try to export the .coverage file as a .coveragexml within Visual Studio (for both MSTest or VSTest), it produces a .coveragexml format that Sonarqube
doesn't accept (it just errors out due to the errors I mentioned above). When I use the "CodeCoverage.exe analyze ..." command to convert the .coverage file from VSTest, it produces a
.coveragexml format that Sonarqube accepts as I receive no errors and can see my code coverage results on the dashboard. Now when I try to use "CodeCoverage.exe analyze ..." command to convert
the .coverage file from MSTest, nothing happens. No .coveragexml file is produced and no errors or any sort of feedback is given. I have also tried writing a C# method to convert the .coverage
file to a .coveragexml file using Microsoft.VisualStudio.Coverage.Analysis. But it produces the same format .coveragexml file as if I were exporting it from Visual Studio.
Other things that might be helpful to know:
I am running the analysis on VB.NET code.
I am using version 2.2 of the VB.NET plugin from Sonarqube.
I am using version 4.3.2 of Sonarqube and version 2.4 of the SonarQube Runner.
I am using Visual Studio 2013 Premium.
(SonarQube errors out)
The format of the .coveragexml file after exporting it from Visual Studio is like this:
<CoverageDSPriv>
<xs:schema ...>
...
</xs:schema>
<Module>
<ModuleName>...</ModuleName>
<ImageSize>...</ImageSize>
...
<NameSpaceTable>
<BlocksCovered>...</BlocksCovered>
...
(SonarQube accepts)
The format of the .coveragexml file after using "CodeCoverage.exe analyze ..." (only works with VSTest's .coverage file)
<?xml version="1.0" encoding="UTF-8" ?>
<results>
<modules>
<module name="..." path="..." id="..." block_coverage="..." line_coverage="..." blocks_covered="..." ... >
<functions>
<function id="..." token="..." name="..." type_name="..." block_coverage="..." >
...
It looks like there are two completely different schemas for this data and SonarQube is only accepting one of them, is that the case? Is there another way to convert the .coverage data to the one that SonarQube accepts?
I have created this XSLT to convert the coveragexml file in the good format.
<xsl:output method="xml" indent="yes"/>
<xsl:template match="CoverageDSPriv">
<results>
<modules>
<xsl:for-each select="Module">
<xsl:element name="module">
<xsl:attribute name="name">
<xsl:value-of select="ModuleName"/>
</xsl:attribute>
<xsl:attribute name="path">
<xsl:value-of select="ModuleName"/>
</xsl:attribute>
<xsl:attribute name="block_coverage">
<xsl:value-of select="BlocksCovered div (BlocksCovered + BlocksNotCovered) * 100"/>
</xsl:attribute>
<xsl:attribute name="line_coverage">
<xsl:value-of select="LinesCovered div (LinesCovered + LinesPartiallyCovered + LinesNotCovered) * 100"/>
</xsl:attribute>
<xsl:attribute name="blocks_covered">
<xsl:value-of select="BlocksCovered"/>
</xsl:attribute>
<xsl:attribute name="blocks_not_covered">
<xsl:value-of select="BlocksNotCovered"/>
</xsl:attribute>
<xsl:attribute name="lines_covered">
<xsl:value-of select="LinesCovered"/>
</xsl:attribute>
<xsl:attribute name="lines_partially_covered">
<xsl:value-of select="LinesPartiallyCovered"/>
</xsl:attribute>
<xsl:attribute name="lines_not_covered">
<xsl:value-of select="LinesNotCovered"/>
</xsl:attribute>
<xsl:for-each select="NamespaceTable">
<xsl:for-each select="Class">
<functions>
<xsl:for-each select="Method">
<xsl:element name="function">
<xsl:attribute name="name">
<xsl:value-of select="substring-before(MethodName, '()')"/>
</xsl:attribute>
<xsl:attribute name="type_name">
<xsl:value-of select="../ClassName"/>
</xsl:attribute>
<xsl:attribute name="block_coverage">
<xsl:value-of select="BlocksCovered div (BlocksCovered + BlocksNotCovered) * 100"/>
</xsl:attribute>
<xsl:attribute name="line_coverage">
<xsl:value-of select="LinesCovered div (LinesCovered + LinesPartiallyCovered + LinesNotCovered) * 100"/>
</xsl:attribute>
<xsl:attribute name="blocks_covered">
<xsl:value-of select="BlocksCovered"/>
</xsl:attribute>
<xsl:attribute name="blocks_not_covered">
<xsl:value-of select="BlocksNotCovered"/>
</xsl:attribute>
<xsl:attribute name="lines_covered">
<xsl:value-of select="LinesCovered"/>
</xsl:attribute>
<xsl:attribute name="lines_partially_covered">
<xsl:value-of select="LinesPartiallyCovered"/>
</xsl:attribute>
<xsl:attribute name="lines_not_covered">
<xsl:value-of select="LinesNotCovered"/>
</xsl:attribute>
<ranges>
<xsl:for-each select="Lines">
<xsl:element name="range">
<xsl:attribute name="source_id">
<xsl:value-of select="SourceFileID"/>
</xsl:attribute>
<xsl:attribute name="covered">
<xsl:choose>
<xsl:when test="Coverage=0">yes</xsl:when>
<xsl:when test="Coverage=1">partial</xsl:when>
<xsl:when test="Coverage=2">no</xsl:when>
</xsl:choose>
</xsl:attribute>
<xsl:attribute name="start_line">
<xsl:value-of select="LnStart"/>
</xsl:attribute>
<xsl:attribute name="start_column">
<xsl:value-of select="ColStart"/>
</xsl:attribute>
<xsl:attribute name="end_line">
<xsl:value-of select="LnEnd"/>
</xsl:attribute>
<xsl:attribute name="end_column">
<xsl:value-of select="ColEnd"/>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</ranges>
</xsl:element>
</xsl:for-each>
</functions>
<source_files>
<xsl:for-each select="../../../SourceFileNames">
<xsl:element name="source_file">
<xsl:attribute name="id">
<xsl:value-of select="SourceFileID"/>
</xsl:attribute>
<xsl:attribute name="path">
<xsl:value-of select="SourceFileName"/>
</xsl:attribute>
</xsl:element>
</xsl:for-each>
</source_files>
</xsl:for-each>
</xsl:for-each>
</xsl:element>
</xsl:for-each>
</modules>
</results>
</xsl:template>
I think you've perfectly described the situation: There indeed are two totally different code coverage reports, which both uses the *.coveragexml extension.
The C# and VB.NET plugin only support one of those formats at the moment, and a ticket exists to add the support for the other: https://jira.codehaus.org/browse/SONARNTEST-3
I have a WiX installer to install and start a service. However, all the examples I find place the ServiceInstall tag directly below the file tag for the .exe file to be installed as a service.
I can’t do this as I am using heat to generate my file elements in a separate file. So my wix script looks like this:
<Directory Id="INSTALLLOCATION" Name="Email Generation Service">
<Component Id="SetupService" Guid="51E78696-80E0-4CDA-8F49-902C67CB129C">
<CreateFolder />
<ServiceInstall Id="ServiceInstaller"
Type="ownProcess"
Vital="yes"
Name="EmailGenerationService"
DisplayName="Email Generation Service"
Description="Service for generating Emails from Nexus"
Start="auto"
Account="LocalService"
ErrorControl="ignore"
Interactive="no">
</ServiceInstall>
<ServiceControl Id="StartService" Start="install" Stop="both" Remove="uninstall" Name="EmailGenerationService" Wait="yes" />
</Component>
</Directory>
How can I tell WiX which file I want to install as a service?
I have used XSLT to set the KeyPath on all files to no, with the exception of the file I want to install, despite the fact that all files are in their own component. I am at a bit of a loss now :(
A service must be linked to a specific file. This is a Windows Installer limitation. So one way or another you need to create the ServiceInstall element under your EXE file element.
A solution would be to hard-code the EXE file instead of letting it be generated automatically.
Adding this as relevant information, I had a similar problem and used a similar solution to you, adding an xml transform. However, I used the transform to insert the service control/install elements into the heat-generated fragment. I've pasted my transform below, you may have to modify properties or remove items you don't need.
Some things to note:
The service control doesn't auto-start the service on install, I had
issues with assembly refs not being populated by the time the msi tried to invoke them
A key part of the XSLT adds
an "include" statement at the top of the heat.exe file so that I can
reference variables from my .wxi file
This assumes the variable name
you told heat to inject as your -var parameter is "var.SourcePath"
I never extracted the name of the .exe file or settings file out as
variables that can be injected into the transform because they were
fairly stable and it seemed...difficult
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:wix="http://schemas.microsoft.com/wix/2006/wi"
xmlns="http://schemas.microsoft.com/wix/2006/wi">
<xsl:output method="xml" version="1.0" encoding="UTF-8" indent="yes"/>
<!-- Template for the new ServiceInstall element -->
<xsl:param name="pServiceInstall">
<xsl:element name="ServiceInstall">
<xsl:attribute name="Id">SVINSTL_$(var.ServiceName)</xsl:attribute>
<xsl:attribute name="Description">$(var.ServiceInstallDescription)</xsl:attribute>
<xsl:attribute name="Account">$(var.SystemAccount)</xsl:attribute>
<xsl:attribute name="DisplayName">$(var.ServiceInstallDisplayName)</xsl:attribute>
<xsl:attribute name="ErrorControl">normal</xsl:attribute>
<xsl:attribute name="Name">$(var.ServiceName)</xsl:attribute>
<xsl:attribute name="Interactive">no</xsl:attribute>
<xsl:attribute name="Start">auto</xsl:attribute>
<xsl:attribute name="Type">ownProcess</xsl:attribute>
<xsl:attribute name="Vital">yes</xsl:attribute>
</xsl:element>
</xsl:param>
<!-- Template for the new ServiceControl element -->
<xsl:param name="pServiceControl">
<xsl:element name="ServiceControl">
<xsl:attribute name="Id">SVCTRL_$(var.ServiceName)</xsl:attribute>
<xsl:attribute name="Name">$(var.ServiceName)</xsl:attribute>
<xsl:attribute name="Stop">both</xsl:attribute>
<xsl:attribute name="Remove">uninstall</xsl:attribute>
<xsl:attribute name="Wait">yes</xsl:attribute>
</xsl:element>
</xsl:param>
<!-- Insert a ?include statement at the top of the fragment so it can use config variables -->
<xsl:template match="wix:Wix">
<xsl:copy>
<xsl:processing-instruction name="include">InstallerSettings.wxi</xsl:processing-instruction>
<xsl:apply-templates/>
</xsl:copy>
</xsl:template>
<!-- Turn the file name of the executable into a variable so it can be targeted for shortcuts,etc -->
<xsl:template match="#Source[. ='$(var.SourcePath)\HARD_CODED_NAME_OF_PROJECT.exe']">
<xsl:call-template name="identity" />
<xsl:attribute name="Id">$(var.ServiceExecutableFileId)</xsl:attribute>
</xsl:template>
<!-- Insert the ServiceInstall and ServiceControl elements into the component with the exe file -->
<xsl:template match="//wix:File[#Source='$(var.SourcePath)\HARD_CODED_NAME_OF_PROJECT.exe']">
<xsl:call-template name="identity" />
<xsl:copy-of select="$pServiceInstall"/>
<xsl:copy-of select="$pServiceControl"/>
</xsl:template>
<!-- Identity template (copies everything as is) -->
<xsl:template match="#*|node()" name="identity">
<xsl:copy>
<xsl:apply-templates select="#*|node()" />
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
I'm compiling a NAnt project on linux with TeamCity Continuous Integration server. I have been able to generate a test report by running NAnt on mono thru a Command Line Runner but don't have the options of using the report like a NAnt Runner. I'm also using MBUnit for the testing framework.
How can I merge in the test report and display "Tests failed: 1 (1 new), passed: 3049" for the build?
Update: take a look at MBUnitTask its a NAnt task that uses sends messages that TeamCity expects from NUnit so it lets you use all of TeamCity's features for tests.
MBUnitTask
Update: Galio has better support so you just have to reference the Galio MBUnit 3.5 dlls instead of the MBUnit 3.5 dlls and switch to the galio runner to make it work.
Gallio now has an extension to output TeamCity service messages.
Just use the included Gallio.NAntTasks.dll and enable the TeamCity extension. (this won't be necessary in the next release)
TeamCity watches the command line output from the build. You can let it know how your tests are going by inserting certain markers into that output See http://www.jetbrains.net/confluence/display/TCD3/Build+Script+Interaction+with+TeamCity. For example
##teamcity[testSuiteStarted name='Test1']
will let TeamCity know that a set of tests started. With MbUnit you can't output these markers while the tests are running, but you can transform the XML file that it outputs. Here is the XSL that I am using:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="assemblies/assembly">
##teamcity[testSuiteStarted name='<xsl:value-of select="#name" />']
<xsl:apply-templates select="//run" />
##teamcity[testSuiteFinished name='<xsl:value-of select="#name" />']
</xsl:template>
<xsl:template match="run">
<xsl:choose>
<xsl:when test="#result='ignore' or #result='skip'">
##teamcity[testIgnored name='<xsl:value-of select="#name" />' message='Test Ignored']
</xsl:when>
<xsl:otherwise>
##teamcity[testStarted name='<xsl:value-of select="#name" />']
</xsl:otherwise>
</xsl:choose>
<xsl:if test="#result='failure'">
##teamcity[testFailed name='<xsl:value-of select="#name" />' message='<xsl:value-of select="child::node()/message"/>' details='<xsl:value-of select="normalize-space(child::node()/stack-trace)"/>']
</xsl:if>
<xsl:if test="#result!='ignore' and #result!='skip'">
##teamcity[testFinished name='<xsl:value-of select="#name" />']
</xsl:if>
</xsl:template>
</xsl:stylesheet>
Here's what I came up with
How can I merge in the test report?
First you'll need to get mbunit to generate both an XML and HTML report. The Command line arguments look like this
/rt:Xml /rt:Html /rnf:mbunit /rf:..\reports
this will generate the reports into a dir called reports and the file will be called mbunit.xml and mbunit.html
next we want to add these files as artifacts on the build
build\reports\* => Reports
the last step is to tell teamcity to add it as a tab for the build
find the .BuildServer\config\main-config.xml and add this line
(on windows this is in c:\Documents and Settings\, on linux it was in the /root dir)
<report-tab title="Tests" basePath="Reports" startPage="mbunit.html" />
How can I display "Tests failed: 1 (1 new), passed: 3049" for the build?
TeamCity looks for a file called teamcity-info.xml where you can stick messages in to be displayed. The Actual test count is actually just plain text. I think you can just add the file as an artifact but I've also got it in the root dir of the build.
in NAnt you'll want to use this command to do an XSLT on the MBUnit XML Report
<style style="includes\teamcity-info.xsl" in="reports\mbunit.xml" out="..\teamcity-info.xml" />
the actual xsl looks like this.
(Note: that the { and } are reserved in xsl so we have to use params)
<?xml version="1.0" encoding="ISO-8859-1"?>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:param name="cbl" select="'{'"/>
<xsl:param name="cbr" select="'}'"/>
<xsl:template match="/">
<xsl:for-each select="report-result/counter">
<build number="1.0.{concat($cbl,'build.number',$cbr)}">
<xsl:if test="#failure-count > 0">
<statusInfo status="FAILURE">
<text action="append"> Tests failed: <xsl:value-of select="#failure-count"/>, passed: <xsl:value-of select="#success-count"/></text>
</statusInfo>
</xsl:if>
<xsl:if test="#failure-count = 0">
<statusInfo status="SUCCESS">
<text action="append"> Tests passed: <xsl:value-of select="#success-count"/></text>
</statusInfo>
</xsl:if>
</build>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
This will give you a file that looks like this
<build number="1.0.{build.number}">
<statusInfo status="FAILURE">
<text action="append">Tests failed: 16, passed: 88</text>
</statusInfo>
</build>
TeamCity Sidebar Gadget for Windows Vista, Windows 7
http://teamcity-gadget.com