3

I'm building a .Net 6 WPF application in Visual Studio 2022 and I'm publishing to a folder.

I'd like the assembly version included in the folder path e.g. C:\Code\Publish\MyApplication_1.2.0.28\

My Google Fu is failing me and I can't find a solution.

I'm using a Text Template to generate the Assembly Version from a manually set <major>.<minor>.<patch>. and an autoincrementing <revision>. See below. This works exceptionally well. Thanks to https://makolyte.com/auto-increment-build-numbers-in-visual-studio/ including comments.

Following this StackOverflow I tried creating and calling a static method getting the assembly version from the publishprofile. I added the method to the .tt just to keep it together. The static method works if I just call it from MainWindow, but when editing the FolderProfile.pubxml as text and adding the call to the PublishDir: <PublishDir>C:\Code\Publish\MyApplication\$([VersionGetter]::GetVersion())</PublishDir> and hitting the Publish-button, it opens the wizard to create a new publishprofile, so that is not correct syntax. From the linked documentation, it looks like I can call certain types from here. It works creating a GUID string with the following, so I guess that's just not the way to go: <PublishDir>C:\Code\Publish\MyApplication\$([System.Guid]::NewGuid())</PublishDir>

I actually stumpled upon this StackOverflow answer, but I'm unsure of how to implement it. It creates a directory, but how does the publish profile know about this directory? See code from that answer at the buttom.

So, StackOverflow, please help me :)

FolderProfile.pubxml

<?xml version="1.0" encoding="utf-8"?>
<!--
https://go.microsoft.com/fwlink/?LinkID=208121.
-->
<Project>
    <PropertyGroup>
        <Configuration>Release</Configuration>
        <Platform>Any CPU</Platform>
        <PublishDir>C:\Code\Publish\MyApplication\</PublishDir>
        <PublishProtocol>FileSystem</PublishProtocol>
        <TargetFramework>net6.0-windows</TargetFramework>
        <RuntimeIdentifier>win-x64</RuntimeIdentifier>
        <SelfContained>true</SelfContained>
        <PublishSingleFile>true</PublishSingleFile>
        <PublishReadyToRun>false</PublishReadyToRun>
    </PropertyGroup>
</Project>

Added this to .csproj file

<PropertyGroup>
    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

<Import Project="$(MSBuildExtensionsPath)\Microsoft\VisualStudio\v$(VisualStudioVersion)\TextTemplating\Microsoft.TextTemplating.targets" />

<!-- Automatic versioning end -->

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
    <DebugType>embedded</DebugType>
</PropertyGroup>

<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
    <DebugType>embedded</DebugType>
    <TransformOnBuild>true</TransformOnBuild>
    <OverwriteReadOnlyOutputFiles>true</OverwriteReadOnlyOutputFiles>
    <TransformOutOfDateOnly>false</TransformOutOfDateOnly>
</PropertyGroup>

Text Template: VersionAutoIncrement.tt

<#@ template debug="false" hostspecific="true" language="C#" #>
<#@ output extension=".cs" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.IO" #>
<#@ import namespace="System.Linq" #>
<#

    try
    {
        string currentDirectory = Path.GetDirectoryName(this.Host.TemplateFile);
        string fullPath = Path.Combine(currentDirectory, "VersionAutoIncrement.cs");

        string currentRevisionNumber = File.ReadLines(fullPath).First().Replace("//", "");

        Revision = Convert.ToUInt16(currentRevisionNumber);
        Revision++;
    }
    catch( Exception )
    {
        //Throws the first time since the output file doesn’t exist yet
    }
#>
//<#= this.Revision #>
using System.Reflection;
[assembly: AssemblyVersion("1.2.0.<#= this.Revision #>")]

namespace FlexPOS_Importer
{
    public static class VersionGetter
    {
        public static string GetVersion()
        {
            return Assembly.GetExecutingAssembly().GetName().Version.ToString();
        }
    }
}

<#+
    UInt16 Revision = 1;
#>

The generated VersionAutoIncrement.cs file

//29
using System.Reflection;
[assembly: AssemblyVersion("1.2.0.29")]

namespace FlexPOS_Importer
{
    public static class VersionGetter
    {
        public static string GetVersion()
        {
            return Assembly.GetExecutingAssembly().GetName().Version.ToString();
        }
    }
}

Section copied from this StackOverflow answer

As follows[Altered version of the code as described in the given links]:

<PropertyGroup>
    <AssemblyList>myfolder\myLibrary.dll</AssemblyList>
</PropertyGroup>

<Target Name="AssemblyInformations">    
    <GetAssemblyIdentity AssemblyFiles="$(AssemblyList)">   
        <Output TaskParameter="Assemblies" ItemName="AssemblyInfos"/>
    </GetAssemblyIdentity>
</Target>
<Message Text="Files: %(AssemblyInfos.Version)"/> 

And then I would use something like the following to create a directory in the place you want to publish:

<CreateProperty Value="$(Public_Shared_Folder)$(ProjectName)\">   
    <Output TaskParameter="Value" PropertyName="PublicFolderToDropZip" />
</CreateProperty> 
<MakeDir Directories="$(PublicFolderToDropZip)" 
         Condition="$(Configuration)=='Release' AND Exists('$(PublicFolderToDropZip)')" /> 

The entire operation can be completely automated.

SvendK
  • 465
  • 3
  • 17
  • For anyone ending up on this page after an internet search, I have created a new post for the Visual Studio team. Please go and vote for it: https://developercommunity.visualstudio.com/t/Publish-to-folder:-Add-variables-to-the/10369195 – SvendK May 19 '23 at 07:49

0 Answers0