在我的脑海中,要么创建一个构建时的转换T4,它将 .cs/type 名称的类/字典构建为哈希/时间戳,或者将该属性标记并挂钩到 MSBuild 的BeforeBuild事件以在编译之前将其替换为类似哈希/上次修改。
编辑:好的,这里有几个非常粗略的例子。
T4 -- 在您的项目 (.tt) 中创建一个文本模板并粘贴以下内容
<#@ template hostspecific="true" #>
<#@ import namespace="System" #>
<#@ import namespace="System.IO" #>
namespace ClassLibrary1
{
public class Version
{
<# var project = new FileInfo(Host.ResolvePath("ClassLibrary1.csproj"));
WriteLine("// " + project.FullName);
var files = project.Directory.GetFileSystemInfos("*.cs", SearchOption.AllDirectories);
foreach (var file in files)
{
var name = Path.GetFileNameWithoutExtension(file.Name);
if (name == "Version")
continue; #>
public const long <#= name #> = <#= file.LastWriteTime.Ticks #>;
<# } #>
}
}
您现在将拥有一个可以通过 Version.ClassName 常量在比较中使用的类。
MSBuild - 编辑您的 .csproj 并在末尾添加以下内容。
<UsingTask TaskName="Version" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<Files ParameterType="Microsoft.Build.Framework.ITaskItem[]" Required="true" />
</ParameterGroup>
<Task>
<Using Namespace="System.IO" />
<Using Namespace="System.Text.RegularExpressions" />
<Code Type="Fragment" Language="cs"><![CDATA[
var regex = new Regex(@"Version = (\d+);//(-?\d+)");
foreach (var file in Files)
{
var source = File.ReadAllText(file.ItemSpec);
var match = regex.Match(source);
if (!match.Success) continue;
var hash = regex.Replace(source, string.Empty).GetHashCode();
if (int.Parse(match.Groups[2].Value) == hash) continue;
source = regex.Replace(source, string.Format("Version = {0};//{1}", int.Parse(match.Groups[1].Value) + 1, hash));
File.WriteAllText(file.ItemSpec, source);
}
]]></Code>
</Task>
</UsingTask>
<Target Name="BeforeBuild">
<Version Files="@(Compile)" />
</Target>
然后添加public const int Version = 0;//0
到您的班级。在编译之前,MSBuild 将获取文件的哈希值,如果前一个不匹配,则更新计数器。
在这些示例中有一个可以做得更好的 crapton,但希望它们能说明您可以采取的方向。可能有更好的方法,这是在使用 Mono.Cecil 对 IL 进行哈希处理后突然出现在我脑海中的前两个想法,我发现这个问题很有趣。如果您确实走任何一条路线,我建议您阅读 T4 及其Host
以及如何在构建时强制重新生成,或 MSBuild 和扩展事件、自定义和内联任务,甚至可能进入EnvDTE
, CodeDOM
,Microsoft.Build.Evaluation
命名空间等,而不仅仅是搜索 .cs 文件和正则表达式。