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.