我正在尝试为.Net中的C#项目设置一个正确的自动版本控制方法。
要求是:
我找到了一个解决方案,可以提供我想要的版本字符串。但是,为了使程序集在构建之后反映出这个版本,我需要在构建之前更改assemblyInfo.cs文件。我最终通过添加要在预构建事件上运行的脚本来启用此功能。根据Microsoft文档,这应该没问题:
Pre-build events do not run if the project is up to date and no build is triggered.
(参考:http://msdn.microsoft.com/en-us/library/42x5kfw4.aspx):
这是不正确的!预构建事件脚本始终执行 - 即使项目是最新的!那是。即使没有重新编译(因为它是最新的),预运行脚本也会运行。由于我的脚本更新了assemblyInfo.cs文件,项目不再是最新的,所以它重新编译(由于bug / designflaw我必须添加指令来禁用缓存)。这意味着项目重新编译每个时间,这当然不是我想要的 - 考虑到我的解决方案中有103个项目...
我通过在项目文件中添加BeforeBuild和BeforeCompile目标进一步调查了这一点。猜猜看:即使项目是最新的,他们也会每次运行。我已经尝试从Visual Studio和MSBuild运行构建同样令人遗憾的结果。
当项目不是最新时,是否有人建议如何让脚本运行**?
BTW:建议之前: 我已经回顾了网上可用的大多数解决方案,包括通过assemblyInfo.cs中的“1. *”说明符自动增量。 这不是我想要的。我的版本控制需求稍微复杂一些。
答案 0 :(得分:2)
似乎没有人对此有任何解决方案,但经过额外调查后,我终于找到了解决方法。
在调查了Microsoft.CSharp.targets文件之后,我发现CoreCompile中没有“钩子”只在运行CoreCompile时调用目标。 CoreCompile本身依赖于输入和输出的比较来确定它是否应该运行。有了这些信息,我从CoreCompile复制了输入和输出规范,并且瞧瞧:)
我的自定义BeforeCompile任务现在是这样的:
<Target
Name="BeforeCompile"
Inputs="$(MSBuildAllProjects);
@(Compile);
@(_CoreCompileResourceInputs);
$(ApplicationIcon);
$(AssemblyOriginatorKeyFile);
@(ReferencePath);
@(CompiledLicenseFile);
@(EmbeddedDocumentation);
$(Win32Resource);
$(Win32Manifest);
@(CustomAdditionalCompileInputs)"
Outputs="@(DocFileItem);
@(IntermediateAssembly);
@(_DebugSymbolsIntermediatePath);
$(NonExistentFile);
@(CustomAdditionalCompileOutputs)">
<Message Text="BeforeCompile (only when project is not up-to-date)"/>
</Target>
它看起来有些笨拙,但它确实有效。输入和输出也可能相当安全。看不出微软经常改变它们的任何好理由......