Search code examples
c#visual-studio-2015msbuildoffice-addinsmsbuild-task

C# - Unable to change ApplicationVersion from MSBuild script


I'm a newbie trying to modify on publish the ApplicationVersion value by AssemblyVersion one on a MS Office AddIn. Here is my csproj :

<Target Name="SetAssemblyVersionToPublish" AfterTargets="AfterCompile">
<ReadLinesFromFile File="Properties\AssemblyInfo.cs">
  <Output TaskParameter="Lines" ItemName="AssemblyVersion" />
</ReadLinesFromFile>
<PropertyGroup>
  <In>@(AssemblyVersion)</In>
  <Pattern>\[assembly: AssemblyVersion\(.(\d+)\.(\d+)\.(\d+).(\d+)</Pattern>
  <Out>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern)))</Out>
  <ApplicationVersion>$(Out.Remove(0, 28))</ApplicationVersion>
</PropertyGroup>
<Message Text="app Version : $(ApplicationVersion)" Importance="High" />

When I publish the app from Visual Studio 2015, logs show the good version :

app Version : 4.4.9.0

But in fact it is the ApplicationVersion defined in VS that is used :

<ApplicationVersion>1.0.0.0</ApplicationVersion>

App_1_0_0_0

I already tried :

  • reset all VS settings
  • disable any vs third party extensions
  • use safemode
  • if I publish a WPF app, it works well

Any one would know why I get this change ?


Update

After some test, I found that MSBUILD use a different target file for VSTO : MSBuild\Microsoft\VisualStudio\v14.0\OfficeTools\Microsoft.VisualStudio.Tools.Office.targets. It seems to use PublishVersion which is a copy of ApplicationVersion. I don't know why but if I set ApplicationVersion in my target, it does not update the PublishVersion... If I set the publishVersion, I get the good version in my bin folder, but publishing failed (don't copy to publish folder because it still want to get the folder with 1_0_0_0 in bin). It may be a problem with a bad step which launch my target, but I don't figure when it must be done.

Any help ?


UPDATE 2

It seems to be a bug with VS2015 publishing tool. If I try with msbuild.exe command line, it works well:

On VS I get an error asking for the below folder : enter image description here

Whereas with the following msbuild command, it works : MSBuild xxx\ExcelAddIn1\ExcelAddIn1\ExcelAddIn1.csproj /t:clean;publish

Anyone know what can be done as a workaround ?


Solution

  • First of all, I have a question, when I use your code in a winform project and execute publish, I got an error like:

    enter image description here

    After I test, I found that

    ApplicationVersion which you got is illegal three digits instead of four digits, so there is a problem with your method of obtaining AssemblyVersion.

    In general, the publish version is under Project Properties(right-click on your project)-->Publish

    enter image description here

    You can note that it is four digits.

    Which proves that you have miss a node on Pattern property.

    Suggestion

    You should use

     <Pattern>\[assembly: AssemblyVersion\(.(\d+)\.(\d+)\.(\d+).(\d+)</Pattern>
    

    The whole code are:

     <Target Name="AfterCompile">
        <ReadLinesFromFile File="Properties\AssemblyInfo.cs">
          <Output TaskParameter="Lines" ItemName="AssemblyVersion" />
        </ReadLinesFromFile>
        <PropertyGroup>
          <In>@(AssemblyVersion)</In>
          <Pattern>\[assembly: AssemblyVersion\(.(\d+)\.(\d+)\.(\d+).(\d+)</Pattern>
          <Out>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern)))</Out>
          <ApplicationVersion>$(Out.Remove(0, 28))</ApplicationVersion>
        </PropertyGroup>
        <Message Text="app Version : $(ApplicationVersion)" Importance="High" />
      </Target>
    

    It will reads the AssemblyVersion from the AssemblyInfo.cs file.

    In my side, it is

    enter image description here

    Actually, your method already works and it overwrite the publish version for the app.

    I think you have read the first part of the build output log like this:

    enter image description here

    It is only the default system initial value at the beginning of the build, and it is just displayed there. And then through your custom msbuild script actually has overwritten its value.

    enter image description here

    Before executing publish, you should delete the publish folder, bin and obj folder, then execute the publish, you can enter the folder to check:

    enter image description here

    enter image description here

    Update 1

    I think your csproj file has imported some targets or props file which has other targets overwrite the AfterCompile target. So your method failed.

    That is, your method may be overwritten elsewhere.

    So I think you should not use AfterCompile as the target name and should name it as another to distinguish between them.

    Use this:

    <Target Name="SetAssemblyVersionToPublish" AfterTargets="AfterCompile">
        <ReadLinesFromFile File="Properties\AssemblyInfo.cs">
          <Output TaskParameter="Lines" ItemName="AssemblyVersion" />
        </ReadLinesFromFile>
        <PropertyGroup>
          <In>@(AssemblyVersion)</In>
          <Pattern>\[assembly: AssemblyVersion\(.(\d+)\.(\d+)\.(\d+).(\d+)</Pattern>
          <Out>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern)))</Out>
          <ApplicationVersion>$(Out.Remove(0, 28))</ApplicationVersion>
        </PropertyGroup>
        <Message Text="app Version : $(ApplicationVersion)" Importance="High" />
      </Target>
    

    Or, You can add a file called Directory.Build.targets file on your project folder and then add my code on it:

    enter image description here

     <Project>
        <Target Name="SetAssemblyVersionToPublish" AfterTargets="AfterCompile">
            <ReadLinesFromFile File="Properties\AssemblyInfo.cs">
              <Output TaskParameter="Lines" ItemName="AssemblyVersion" />
            </ReadLinesFromFile>
            <PropertyGroup>
              <In>@(AssemblyVersion)</In>
              <Pattern>\[assembly: AssemblyVersion\(.(\d+)\.(\d+)\.(\d+).(\d+)</Pattern>
              <Out>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern)))</Out>
              <ApplicationVersion>$(Out.Remove(0, 28))</ApplicationVersion>
            </PropertyGroup>
            <Message Text="app Version : $(ApplicationVersion)" Importance="High" />
          </Target>
      </Project>
    

    Then, delete bin, obj, publish folder and then republish again to check it.

    If the issue still persists, you should try the following suggestions to troubleshoot the issue:

    1) Try to reset vs settings by Tools-->Import and Export settings-->Reset all vs settings

    2) disable any vs third party extensions under Tools-->Extensions and Updates -->Installed, after that, close VS ,restart your project.

    3) you could try devenv /safemode on the Developer Command Prompt for VS2015 to start a pure, initial vs to test your solution.

    ===============================================

    Update 2

    The MS Office Excel AddIn project is quite different from the traditional projects. And it is impossible by using this way.

    As a workaround, I think you should use msbuild script to publish the project.

    1) create a file called PublishExcel.proj

    2) add these content on that file:

    <?xml version="1.0" encoding="utf-8"?>
    <Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    
    <Target Name="SetAssemblyVersionToPublish">
    <!--you must specify the full path of the AssemblyInfo.cs from your project -->
    <ReadLinesFromFile File="C:\Users\xxx\Documents\Visual Studio 2015\Projects\ExcelAddIn1\ExcelAddIn1\Properties\AssemblyInfo.cs"> 
      <Output TaskParameter="Lines" ItemName="AssemblyVersion" />
    </ReadLinesFromFile>
    <PropertyGroup>
      <In>@(AssemblyVersion)</In>
      <Pattern>\[assembly: AssemblyVersion\(.(\d+)\.(\d+)\.(\d+).(\d+)</Pattern>
      <Out>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern)))</Out>
      <ApplicationVersion>$(Out.Remove(0, 28))</ApplicationVersion>
    </PropertyGroup>
    <Message Text="app Version : $(ApplicationVersion)" Importance="High" />
    
    <MSBuild Projects="C:\Users\Administrator\Documents\Visual Studio 2015\Projects\ExcelAddIn1\ExcelAddIn1\ExcelAddIn1.csproj" Properties="ApplicationVersion=$(ApplicationVersion)" Targets="Publish">
       </MSBuild>
    </Target>
    </Project>
    

    3) then open Developer Command prompt for VS2015 and then type:

    msbuild xxx\xxx\PublishExcel.proj -t:SetAssemblyVersionToPublish
    

    And the publish folder will be under the bin\Debug or Release\app.publish folder.

    This function will work for MS Office Excel AddIn project.