How to synchronise the publish version to the assembly version in a .NET ClickOnce application?

后端 未结 5 1412
甜味超标
甜味超标 2020-12-14 01:10

In my C# ClickOnce application, there is an auto-incremented publish version in the Project -> Properties -> Publish tab. I\'d like to display that version

相关标签:
5条回答
  • 2020-12-14 01:24

    I modified my .csproj file to update the assembly version. I created a configuration called "Public Release" for this, but it's not required to do that.

      <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
      <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
           Other similar extension points exist, see Microsoft.Common.targets.
      <Target Name="BeforeBuild">
      </Target>
      <Target Name="AfterBuild">
      </Target>
      -->
      <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
        <MSBuildCommunityTasksPath>$(SolutionDir)Tools\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
      </PropertyGroup>
      <!-- Required Import to use MSBuild Community Tasks -->
      <Import Project="$(SolutionDir)Tools\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets" Condition="'$(BuildingInsideVisualStudio)' == 'true'" />
      <Target Name="BeforeCompile" Condition="'$(BuildingInsideVisualStudio)|$(Configuration)' == 'true|PublicRelease'">
        <FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
          <Output TaskParameter="OutputVersion" PropertyName="AssemblyVersionToUse" />
        </FormatVersion>
        <AssemblyInfo CodeLanguage="CS" OutputFile="$(ProjectDir)Properties\VersionInfo.cs" AssemblyVersion="$(AssemblyVersionToUse)" AssemblyFileVersion="$(AssemblyVersionToUse)" />
      </Target>
    

    The published version may be:

    ApplicationDeployment.CurrentDeployment.CurrentVersion
    
    0 讨论(0)
  • 2020-12-14 01:33

    sylvanaar's last line looks like the way to go, in my experience; but with the caveat that it is only available to deployed versions of the application. For debugging purposes, you might want something like:

        static internal string GetVersion()
        {
            if (ApplicationDeployment.IsNetworkDeployed)
            {
                return ApplicationDeployment.CurrentDeployment.CurrentVersion.ToString();
            }
    
            return "Debug";
        }
    
    0 讨论(0)
  • 2020-12-14 01:39

    I modified sylvanaar's solution for use with VB:

    - Microsoft.VisualBasic.targets instead of Microsoft.CSharp.targets
    - CodeLanguage="VB" instead of CodeLanguage="CS" 
    - AssemblyInfo.vb instead of VersionInfo.cs
    

    , differences in paths:

    - $(SolutionDir).build instead of $(SolutionDir)Tools\MSBuildCommunityTasks
    - $(ProjectDir)AssemblyInfo.vb instead of $(ProjectDir)Properties\VersionInfo.cs
    

    , and to remove conditions:

    - Condition="'$(BuildingInsideVisualStudio)' == 'true'"
    - Condition="'$(BuildingInsideVisualStudio)|$(Configuration)' == 'true|PublicRelease'"
    

    I also synchronized Company and Product with ClickOnce PublisherName and ProductName respectively and generated a Copyright based on the current date:

    - AssemblyCompany="$(PublisherName)"
    - AssemblyProduct="$(ProductName)" 
    - AssemblyCopyright="© $([System.DateTime]::Now.ToString(`yyyy`)) $(PublisherName)"
    

    I ended up adding this to my vbproj file. It requires the MSBuildTasks NuGet package to be installed first:

      <Import Project="$(MSBuildBinPath)\Microsoft.VisualBasic.targets" />
      <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
        <MSBuildCommunityTasksPath>$(SolutionDir).build</MSBuildCommunityTasksPath>
      </PropertyGroup>
      <Import Project="$(MSBuildCommunityTasksPath)\MSBuild.Community.Tasks.Targets" Condition="'$(BuildingInsideVisualStudio)' == 'true'" />
      <Target Name="BeforeCompile">  
        <FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
          <Output TaskParameter="OutputVersion" PropertyName="AssemblyVersionToUse" />
        </FormatVersion>
        <AssemblyInfo CodeLanguage="VB" OutputFile="$(ProjectDir)AssemblyInfo.vb" AssemblyVersion="$(AssemblyVersionToUse)" AssemblyFileVersion="$(AssemblyVersionToUse)" AssemblyCompany="$(PublisherName)" AssemblyProduct="$(ProductName)" AssemblyCopyright="© $([System.DateTime]::Now.ToString(`yyyy`)) $(PublisherName)"/>
      </Target>
    

    I'm not sure how much the location within the project file matters, but I added this to the end of my project file, just before:

    </Project>
    
    0 讨论(0)
  • 2020-12-14 01:40

    I would like to expand on Sylvanaar's answer, as some of implementation details weren't obvious to me. So:

    1. Manually install community build tasks found at: https://github.com/loresoft/msbuildtasks/releases Note: Don't install by nuget if you clean your packages, as the build will fail before getting a chance to restore the packages, since msbuildtasks are referenced as a task in the build file. I put these in folder next to solution file called .build

    2. Add a completely empty file to your projects properties folder called VersionInfo.cs

    3 Remove these lines if they exist in AssemblyInfo.cs

    [assembly: AssemblyVersion("1.0.*")]
    [assembly: AssemblyFileVersion("1.0.*")]
    

    4 Modify your csproj file

      <!-- Include the build rules for a C# project. -->
      <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
    
      <!--INSERT STARTS HERE-->
      <!--note the use of .build directory-->
      <PropertyGroup Condition="'$(BuildingInsideVisualStudio)' == 'true'">
        <MSBuildCommunityTasksPath>$(SolutionDir)\.build\MSBuildCommunityTasks</MSBuildCommunityTasksPath>
      </PropertyGroup>
      <!-- Required Import to use MSBuild Community Tasks -->
      <Import Project="$(SolutionDir)\.build\MSBuild.Community.Tasks.targets" Condition="'$(BuildingInsideVisualStudio)' == 'true'" />
      <Target Name="BeforeCompile" Condition="'$(BuildingInsideVisualStudio)|$(Configuration)' == 'true|Release'">
        <FormatVersion Version="$(ApplicationVersion)" Revision="$(ApplicationRevision)">
          <Output TaskParameter="OutputVersion" PropertyName="AssemblyVersionToUse" />
        </FormatVersion>
        <AssemblyInfo CodeLanguage="CS" OutputFile="$(ProjectDir)Properties\VersionInfo.cs" AssemblyVersion="$(AssemblyVersionToUse)" AssemblyFileVersion="$(AssemblyVersionToUse)" />
      </Target>
    

    5 Use a method like the following to access the version text:

    public string Version()
    {
        Version version = null;
    
        if (ApplicationDeployment.IsNetworkDeployed)
        {
            version = ApplicationDeployment.CurrentDeployment.CurrentVersion;
        }
        else
        {
            version = typeof(ThisAddIn).Assembly.GetName().Version;
        }
    
        return version.ToString();
    }
    
    0 讨论(0)
  • 2020-12-14 01:41

    I did it the other way around, used a wildcard for my assembly version - 1.0.* - so Visual Studio/MSBuild generated a version number automatically:

    // AssemblyInfo.cs    
    [assembly: AssemblyVersion("1.0.*")]
    

    And then I added the following AfterCompile target to the ClickOnce project to assign synchronize PublishVersion with the assembly version:

    <Target Name="AfterCompile">
        <GetAssemblyIdentity AssemblyFiles="$(IntermediateOutputPath)$(TargetFileName)">
          <Output TaskParameter="Assemblies" ItemName="TargetAssemblyIdentity" />
        </GetAssemblyIdentity>
        <PropertyGroup>
          <PublishVersion>%(TargetAssemblyIdentity.Version)</PublishVersion>
        </PropertyGroup>
    </Target>
    
    0 讨论(0)
提交回复
热议问题