您以哪种方式构建项目?通过 msbuild 命令行还是在 VS IDE 中?
第一个方向:让我们在构建开始之前阅读程序集版本号,然后
将其传递给 outputpath 属性。
我编写了一个脚本,试图在构建开始之前读取版本。但并不完全奏效:(
例如:以类库项目为例。
右键单击项目并选择编辑xx.csproj,将脚本(从In 属性到FourthNum 属性)添加到PropertyGroup:
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{DAB28A16-73AD-4EC5-9F8D-E58CE3EC84BE}</ProjectGuid>
......
<In>$([System.IO.File]::ReadAllText('$(MSBuildProjectDirectory)\properties\AssemblyInfo.cs'))</In>
<Pattern>\[assembly: AssemblyVersion\(.(\d+)\.(\d+)\.(\d+).(\d+)</Pattern>
<FirstNum>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern),System.Text.RegularExpressions.RegexOptions.Multiline).Groups[1].Value)</FirstNum>
<SecondNum>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern),System.Text.RegularExpressions.RegexOptions.Multiline).Groups[2].Value)</SecondNum>
<ThirdNum>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern),System.Text.RegularExpressions.RegexOptions.Multiline).Groups[3].Value)</ThirdNum>
<FourthNum>$([System.Text.RegularExpressions.Regex]::Match($(In), $(Pattern),System.Text.RegularExpressions.RegexOptions.Multiline).Groups[4].Value)</FourthNum>
</PropertyGroup>
它将从 AssemblyInfo.cs 中读取程序集版本号。如果我有一个程序集版本为3.13.8.5。然后FirstNum=3, SecondNum=13 ...
并将输出路径设置为:<OutputPath>C:\Company\UpdaterLauncher\Worker\$(FirstNum).$(SecondNum).$(ThirdNum).$(FourthNum)</OutputPath>
重新加载项目并构建它。您可以在C:\Company\UpdaterLauncher\Worker\3.13.8.5 那里找到构建输出。
注意:
1.这样,因为我们将在调试和发布模式下构建它。我们需要在属性组中为调试和发布设置输出路径值。(2个地方)
2.由于我们仅根据版本定义输出,因此调试输出和发布都将位于同一文件夹中。所以我认为<OutputPath> 会更好:
<OutputPath>C:\Company\UpdaterLauncher\Worker\$(FirstNum).$(SecondNum).$(ThirdNum).$(FourthNum)\$(Configuration)</OutputPath>
3. 在 VS IDE 中更改版本后,此脚本将不会立即运行。
通过命令行:效果很好,每次我们更改版本号并构建它,输出都是正确的。
在VS IDE中:每次我们更改版本后,都需要我们通过右键单击项目来卸载和重新加载项目文件,然后才能工作。所以我说它不是那么完美。(我认为这个问题与VS何时以及如何加载项目文件有关)
第二个方向:构建输出实际上是复制相关的
程序集到输出文件夹。所以我们可以复制或移动输出内容
通过复制或移动任务到构建后我们想要的目录。
我们可以检查this issue,使用GetAssemblyIdentity获取构建后的信息。
使用上面的方式获取版本号,命名为$(MyVersion)。然后使用构建后的目标将输出复制到指定的文件夹。
<Target Name="CopyToSpecificFolder" AfterTargets="build">
<GetAssemblyIdentity
AssemblyFiles="$(OutputPath)$(AssemblyName).dll">
<Output
TaskParameter="Assemblies"
ItemName="MyAssemblyIdentities"/>
</GetAssemblyIdentity>
<PropertyGroup>
<MyVersion>%(MyAssemblyIdentities.Version)</MyVersion>
</PropertyGroup>
<ItemGroup>
<Out Include="$(OutputPath)*.*" />
</ItemGroup>
<Copy DestinationFolder="C:\Company\UpdaterLauncher\Worker\$(MyVersion)" SourceFiles="@(Out)"/>
</Target>
将此脚本添加到 xx.csproj 文件中。在它的底部像:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
......
<Target Name="CopyToSpecificFolder" AfterTargets="build">
......
</Target>
</Project>
无论是 VS IDE 还是命令行,它都能很好地工作。而且是类项目,如果你正在开发一个.exe项目,把$(AssemblyName).dll改成$(AssemblyName).exe。