【发布时间】:2014-09-24 16:11:04
【问题描述】:
我正在尝试以这个问题为基础:
Reading a single value from a file in 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>
当然,这会在文件名中插入完整的版本号,这是我不想要的。
有人对如何进行有任何提示吗?
谢谢。
编辑:通过将以下内容添加到我的 .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>
由于我需要与以前相同的属性定义,我将上面的 sn-p 移动到“通用”目标中,并在此处显示的构建和清理任务中引用它。
彼得 - 如果您想将您的评论作为答案,我会接受。
谢谢!
编辑:按照 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 任务之后,似乎构建了以下目标:
- IncrementalClean(已完成)
- 构建后事件
- CoreBuild
- 构建后
- 构建
其中没有引用任何一个 DLL 名称。
目前看来,这仍然是我最好的选择。
【问题讨论】:
-
为什么不在目标或 AfterBuild 目标的末尾添加一个
元素来重命名二进制文件? -
@PeterRitchie - 如果程序集已签名,它将不起作用。另外,问题是关于构建新路径,而不是什么时候这样做......
-
为什么要程序集名称中的版本?你从中得到了什么好处?
-
在我们的案例中,我们发现需要使用同一个 DLL 的多个版本来部署我们的软件。例如,假设 DLL A 和 B 都依赖于 DLL X 版本 1.0。然后我们生成 DLL X 的 1.1 版,我们开始更新 DLL B 以使用 X 1.1,但 A 仍然使用 X 1.0,没有更新计划。在这种情况下,我们需要同时使用 A、B、X 1.0 和 X 1.1 部署最终产品。无论如何,这不是我们可以控制的;它就是这样儿的。我想做的就是把这个数字集中到一个地方。谢谢。
-
添加链接的 AssemblyVersionl.cs 会不起作用吗?
标签: c# .net dll msbuild version