Search code examples
msbuilduwpappxmanifest

Get UWP Package.appxmanifest version in MSBuild


I need the Package.appxmanifest Version in a MSBuild.Target. What I do is:

<Target Name="Zip">
<ItemGroup>
    <BinDirectoryFiles Include="...\AppPackages\My-App_$(Version)\**\*.*" />
</ItemGroup>
<Zip Files="@(BinDirectoryFiles)" WorkingDirectory="...\AppPackages\My-App_$(Version)" 
ZipFileName="...\Zip\My-App_$(Version).zip" />

(I have shorten the paths and the names)

So this is the target where I zip an app package to upload it to HockeyApp. (If I hardcode the complete file Name with the Version number, than the zip target is working.) But to get the right apppackage and the right Name for the zip file I need the Version which is set in the Package.appxmanifest. But I don't know how to get it in my MSBuild.Target in the .csproj file.


Solution

  • The Package.appxmanifest is just an xml file, so you can either create a custom MSBuild task to read it, or use the MSBuild Extension Pack to get the value.

    The following MSBuild file contains a custom GetPackageVersion that will read the Package.appxmanifest from the current folder and output the version:

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="12.0"
             DefaultTargets="Build"
             xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    
    <Target Name="Build">
      <GetPackageVersion Filename="Package.appxmanifest">
        <Output PropertyName="PackageVersion" TaskParameter="PackageVersion" />
      </GetPackageVersion>
    
      <Message Text="PackageVersion: $(PackageVersion)" />
    </Target>
    
    <UsingTask TaskName="GetPackageVersion" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
      <ParameterGroup>
        <FileName ParameterType="System.String" Required="true" />
        <PackageVersion ParameterType="System.String" Output="true" />
      </ParameterGroup>
      <Task>
        <Reference Include="System.Xml" />
        <Reference Include="System.Xml.Linq" />
        <Using Namespace="System.IO" />
        <Using Namespace="System.Xml.Linq" />
        <Code Type="Fragment" Language="cs"><![CDATA[
          var doc = XDocument.Load(FileName);
          var defaultNamespace = doc.Root.GetDefaultNamespace();
          PackageVersion = doc.Root.Element(defaultNamespace.GetName("Identity")).Attribute("Version").Value;
    ]]></Code>
      </Task>
    </UsingTask>
    
    </Project>