我试图建立在这个问题的基础上:
从 MSBuild 中的文件读取单个值
我的目标是有一个位置来放置多个项目中使用的版本号,并且我还希望其中一个项目的 DLL 文件名中包含版本号的一部分。
根据上面的问题,我已经得到了第一部分,但我在第二部分上遇到了困难,希望得到一些指导。
在我的解决方案中,我设置了一个名为 Version.txt 的纯文本文件,仅包含我的完整版本号:
1.1.0.0
在我的两个项目中,我打开了它们的 AssemblyInfo.cs 文件并删除了 AssemblyVersion 和 AssemblyFileVersion 项目,然后修改了这两个项目以在单独的文件中生成它们,如上面的问题所述。
<ItemGroup>
<VersionFile Include="..\Version.txt" />
</ItemGroup>
<Target Name="BeforeBuild">
<ReadLinesFromFile File="@(VersionFile)">
<Output TaskParameter="Lines" PropertyName="VersionNumber" />
</ReadLinesFromFile>
<Delete Files="Properties\Version.cs" />
<WriteLinesToFile File="Properties\Version.cs" Lines="using System.Reflection%3B

[assembly: AssemblyVersion("$(VersionNumber)")]
[assembly: AssemblyFileVersion("$(VersionNumber)")]" />
</Target>
现在,当我构建时,我会为每个项目生成一个生成的 Properties\Version.cs 文件,该文件用于构建 EXE/DLL 并在其文件属性中显示为“1.1.0.0”。这正是我想要的。
对于DLL,我想将程序集命名为“filename.v1.1.dll”,其中“1.1”来自上面Version.txt 中的前两个组件。我对 Version.txt 的格式很灵活,只要我可以在 EXE/DLL 属性中获取完整的“1.1.0.0”,在 DLL 文件名中获取完整的“1.1”即可。
为了尝试这一点,我将 DLL 的 csproj 文件修改为:
<RootNamespace>dllfile</RootNamespace>
<AssemblyName>dllfile.v$(VersionNumber)</AssemblyName>
当然,这会在文件名中插入完整的版本号,这是我不想要的。
有人对如何进行有任何提示吗?
Thanks.
EDIT:通过将以下内容添加到我的 .csproj BeforeBuild 目标中,我已经能够提取版本号的主要/次要组件:
<ReadLinesFromFile File="@(VersionFile)">
<Output TaskParameter="Lines" PropertyName="VersionNumber" />
</ReadLinesFromFile>
<PropertyGroup>
<VersionNumberFirstDotIndex>$(VersionNumber.IndexOf('.'))</VersionNumberFirstDotIndex>
<VersionNumberMajorStart>0</VersionNumberMajorStart>
<VersionNumberMajorLen>$(VersionNumberFirstDotIndex)</VersionNumberMajorLen>
<VersionNumberMinorStart>$([MsBuild]::Add(1, $(VersionNumberFirstDotIndex)))</VersionNumberMinorStart>
<VersionNumberSecondDotIndex>$(VersionNumber.IndexOf('.', $(VersionNumberMinorStart)))</VersionNumberSecondDotIndex>
<VersionNumberMinorLen>$([MSBuild]::Subtract($([MSBuild]::Subtract($(VersionNumberSecondDotIndex), $(VersionNumberFirstDotIndex))), 1))</VersionNumberMinorLen>
<VersionNumberMajor>$(VersionNumber.Substring($(VersionNumberMajorStart), $(VersionNumberMajorLen)))</VersionNumberMajor>
<VersionNumberMinor>$(VersionNumber.Substring($(VersionNumberMinorStart), $(VersionNumberMinorLen)))</VersionNumberMinor>
<VersionNumberShort>$(VersionNumberMajor).$(VersionNumberMinor)</VersionNumberShort>
</PropertyGroup>
<Message Text="DEBUG1 VersionNumberFull=$(VersionNumber)" Importance="High" />
<Message Text="DEBUG2 VersionNumberAbbrev=$(VersionNumberShort)" Importance="High" />
<Delete Files="Properties\Version.cs" />
<WriteLinesToFile File="Properties\Version.cs" Lines="using System.Reflection%3B

[assembly: AssemblyVersion("$(VersionNumber)")]
[assembly: AssemblyFileVersion("$(VersionNumber)")]" />
我现在唯一缺少的是如何将此 VersionNumberShort 放入 DLL 文件名中。除非有人有更好的主意,否则我可以接受 Peter 的建议并使用 Move 任务:
<Target Name="AfterBuild">
<Move SourceFiles="$(OutputPath)$(AssemblyName).pdb" DestinationFiles="$(OutputPath)$(AssemblyName).v$(VersionNumberShort).pdb" />
<Move SourceFiles="$(OutputPath)$(AssemblyName).dll" DestinationFiles="$(OutputPath)$(AssemblyName).v$(VersionNumberShort).dll" />
</Target>
<Target Name="AfterClean" DependsOnTargets="Common">
<Delete Files="$(OutputPath)$(AssemblyName).v$(VersionNumberShort).pdb" ContinueOnError="true" />
<Delete Files="$(OutputPath)$(AssemblyName).v$(VersionNumberShort).dll" ContinueOnError="true" />
</Target>
由于我需要与以前相同的属性定义,因此我将上面的代码片段移动到“公共”目标中,并在此处显示的构建和清理任务中引用它。
彼得 - 如果您想将您的评论作为答案,我会接受。
Thanks!
EDIT:按照 jdlugosz 的回答,我尝试在我的任务中设置 AssemblyName 。不幸的是,根据顶部列出的原始示例,这似乎仍然没有任何效果:
<Target Name="BeforeBuild">
...
<WriteLinesToFile ... />
<PropertyGroup>
<AssemblyName>dllfile.v$(VersionNumber)</AssemblyName>
</PropertyGroup>
</Target>
我尝试从 Visual Studio 开发人员命令提示符中使用 MSBuild 运行此命令:
msbuild /target:clean projfile.csproj
msbuild /verbosity:diag projfile.csproj > out.txt
在此之前,我将 csproj 文件顶部和“重新定义”中的 重命名为唯一的名称,以便于搜索(例如“dllfileoriginal”与“dllfilemodified”)。
查看输出日志,我找不到任何对修改后的文本的引用;输出中到处都是 dllfileoriginal。
在 WriteLinesToFile 任务之后,看起来构建了以下目标:
- 增量清理(已完成)
- 构建后事件
- 核心构建
- 构建后
- Build
其中没有对任何 DLL 名称的引用。
看起来这仍然是我目前最好的选择。