在visual studio中将git提交哈希设置为dll版本号

在visual studio中将git提交哈希设置为dll版本号,git,visual-studio,versioning,Git,Visual Studio,Versioning,我正在使用visual studio 2013和git开发一个项目 我必须分发项目的一些库,所以我想用当前git提交哈希设置它们的版本号,这样我就可以确定它们使用的是哪个库版本 是否有一种方法可以自动将哈希作为版本号,即使用预生成事件,而不是每次手动执行此操作?查看我在项目中对MSBuild社区任务的修改。我添加了一个名为SemanticVersionItDescripte的任务。请参见下面的用法示例 <SemanticVersionGitDescribe LocalPath="$(MSB

我正在使用visual studio 2013和git开发一个项目

我必须分发项目的一些库,所以我想用当前git提交哈希设置它们的版本号,这样我就可以确定它们使用的是哪个库版本


是否有一种方法可以自动将哈希作为版本号,即使用预生成事件,而不是每次手动执行此操作?

查看我在项目中对MSBuild社区任务的修改。我添加了一个名为SemanticVersionItDescripte的任务。请参见下面的用法示例

<SemanticVersionGitDescribe LocalPath="$(MSBuildProjectDirectory)">
    <Output TaskParameter="SemanticVersion" PropertyName="Version"/>
    <Output TaskParameter="IsRelease" PropertyName="Release"/>
    <Output TaskParameter="AdditionalCommitsCount" PropertyName="AdditionalCommits"/>
    <Output TaskParameter="Hash" PropertyName="Hash"/>
</SemanticVersionGitDescribe>

下面是一些使用资源文件的本机项目可能实现的片段。其想法是向项目中添加一个属性表,该属性表具有一个预构建事件,该事件基于git提交散列创建一个.res文件,并将该.res文件添加为资源。以下是属性表:

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <ImportGroup Label="PropertySheets" />
  <PropertyGroup Label="UserMacros" />
  <PropertyGroup>
    <VersionResourceOut>$(MSBuildProjectDirectory)\version.res</VersionResourceOut>
  </PropertyGroup>
  <ItemGroup>
    <Resource Include="$(VersionResourceOut)" />
  </ItemGroup>
  <Import Project="$(BuildToolsDir)tools\versionrc.targets" />
  <Target Name="CreateGitVersionResource" BeforeTargets="BuildGenerateSources">
    <CallTarget Targets="CreateGitVersionResInBuild" />
    <MakeSameWriteTime SourceFile="$(OutDir)$(TargetName)$(TargetExt)" DestFile="$(VersionResourceOut)"/>
  </Target>
</Project>
其中$(GitVersionDir)通常设置为$(MsbuildProjectDirectory),因为我们在源根目录中有大多数.vcxproj文件

  • 我还希望包含构建日期,以便最终进入StringFileinfo块的FileDescription条目的属性是

    <FileDesc>$(GitVersion) $([System.DateTime]::Now.ToString('HH:mm:ss dd/MM/yyyy'))</FileDesc>
    
    谁的路径存储在$(VersionMainInclude)属性中

  • 所有这些都被送入
    rc.exe
    以创建.res文件。完整命令类似于

    rc /d VRC_INCLUDE=$(VersionMainInclude)
       /d VRC_ORIGINALFILENAME=$(TargetName)$(TargetExt)
       /d VRC_FILETYPE=$(FileType)
       /d VRC_FILEDESCGIT=$(FileDesc)
       /d VRC_COPYRIGHT=VRC_COMPANYNAME \251 $([System.DateTime]::Now.ToString(`yyyy`))
       /fo $(VersionResourceOut) $(MsBuildThisFileDirectory)version.rc
    
  • 请注意,
    MakeSameWriteTime
    技巧将.res文件的修改时间设置为与输出文件相同的时间,以确保每次生成.res文件时预生成事件不会触发新生成。也许有更好的方法可以做到这一点,但这一种对我来说很有效:

    <UsingTask TaskName="MakeSameWriteTime" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
      <ParameterGroup>
        <SourceFile Required="true" ParameterType="System.String"/>
        <DestFile Required="true" ParameterType="System.String"/>
      </ParameterGroup>
      <Task>
        <Code Type="Fragment" Language="cs">
          <![CDATA[
    System.IO.File.SetLastWriteTime( DestFile, System.IO.File.GetLastWriteTime( SourceFile ) );]]>
        </Code>
      </Task>
    </UsingTask>
    
    
    
    
    
  • 这是使用的完整.rc模板:

    #include <winver.h>
    
    #define stringize( x )        stringizei( x )
    #define stringizei( x )       #x
    
    #ifdef VRC_INCLUDE
      #include stringize( VRC_INCLUDE )
    #endif
    
    #ifdef _WIN32
      LANGUAGE 0x9,0x1
      #pragma code_page( 1252 )
    #endif
    
    1 VERSIONINFO
     FILEVERSION    VRC_FILEVERSION
     PRODUCTVERSION VRC_PRODUCTVERSION
     FILEFLAGSMASK  0x1L
     FILEFLAGS      VS_FF_DEBUG
     FILEOS         VOS__WINDOWS32
     FILETYPE       VRC_FILETYPE
    BEGIN
      BLOCK "StringFileInfo"
      BEGIN
        BLOCK "040904E4"
        BEGIN
          VALUE "CompanyName",      stringize( VRC_COMPANYNAME )
          VALUE "FileDescription",  stringize( VRC_FILEDESCRIPTION )
          VALUE "FileVersion",      stringize( VRC_FILEVERSION )
          VALUE "LegalCopyright",   stringize( VRC_COPYRIGHT )
          VALUE "InternalName",     stringize( VRC_ORIGINALFILENAME )
          VALUE "OriginalFilename", stringize( VRC_ORIGINALFILENAME )
          VALUE "ProductName",      stringize( VRC_PRODUCTNAME )
          VALUE "ProductVersion",   stringize( VRC_PRODUCTVERSION )
        END
      END
      BLOCK "VarFileInfo"
      BEGIN
        VALUE "Translation", 0x409, 1200
      END
    END
    
    #包括
    #定义字符串化(x)字符串化(x)
    #定义stringizei(x)#x
    #ifdef VRC_包括
    #包括架线(VRC_包括)
    #恩迪夫
    #ifdef_WIN32
    语言0x9,0x1
    #pragma代码页(1252)
    #恩迪夫
    1版本信息
    文件版本VRC_文件版本
    产品版本VRC\U产品版本
    FILEFLAGSMASK 0x1L
    文件标志VS_FF_调试
    FILEOS VOS_u_WINDOWS32
    文件类型VRC_文件类型
    开始
    阻止“StringFileInfo”
    开始
    块“040904E4”
    开始
    值“CompanyName”,字符串化(VRC_CompanyName)
    值“FileDescription”,字符串化(VRC_FileDescription)
    值“FileVersion”,字符串化(VRC_FileVersion)
    价值“LegalCopyright”,stringize(VRC_版权所有)
    值“InternalName”,字符串化(VRC_ORIGINALFILENAME)
    值“OriginalFilename”,字符串化(VRC_OriginalFilename)
    值“ProductName”,字符串化(VRC\U ProductName)
    值“ProductVersion”,字符串化(VRC\U ProductVersion)
    结束
    结束
    阻止“VarFileInfo”
    开始
    值“Translation”,0x409,1200
    结束
    结束
    
    我们有一堆msbuild代码用于此,但不允许我分发全部代码。不确定您是否能从中获得帮助,但原则是:使用VERSIONINFO结构已定义的资源文件模板。在预构建事件中,使用git rev parse--short HEAD的输出填充模板(以及公司名称等),并调用rc.exe创建.res文件。所有这些代码都存储在属性表中,属性表还将.res文件添加到项目的资源中。因此,对于一个新项目,您所要做的就是导入一个文件,并且一切正常。这似乎是一个很好的解决方案,我将尝试它。ThanksAlexey的答案应该会让你开始学习,对于C#,如果你想,我可以发布一个带有C++代码片段的答案是的,请它会有用的。非常感谢这是我所需要的。
    rc /d VRC_INCLUDE=$(VersionMainInclude)
       /d VRC_ORIGINALFILENAME=$(TargetName)$(TargetExt)
       /d VRC_FILETYPE=$(FileType)
       /d VRC_FILEDESCGIT=$(FileDesc)
       /d VRC_COPYRIGHT=VRC_COMPANYNAME \251 $([System.DateTime]::Now.ToString(`yyyy`))
       /fo $(VersionResourceOut) $(MsBuildThisFileDirectory)version.rc
    
    <UsingTask TaskName="MakeSameWriteTime" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll" >
      <ParameterGroup>
        <SourceFile Required="true" ParameterType="System.String"/>
        <DestFile Required="true" ParameterType="System.String"/>
      </ParameterGroup>
      <Task>
        <Code Type="Fragment" Language="cs">
          <![CDATA[
    System.IO.File.SetLastWriteTime( DestFile, System.IO.File.GetLastWriteTime( SourceFile ) );]]>
        </Code>
      </Task>
    </UsingTask>
    
    #include <winver.h>
    
    #define stringize( x )        stringizei( x )
    #define stringizei( x )       #x
    
    #ifdef VRC_INCLUDE
      #include stringize( VRC_INCLUDE )
    #endif
    
    #ifdef _WIN32
      LANGUAGE 0x9,0x1
      #pragma code_page( 1252 )
    #endif
    
    1 VERSIONINFO
     FILEVERSION    VRC_FILEVERSION
     PRODUCTVERSION VRC_PRODUCTVERSION
     FILEFLAGSMASK  0x1L
     FILEFLAGS      VS_FF_DEBUG
     FILEOS         VOS__WINDOWS32
     FILETYPE       VRC_FILETYPE
    BEGIN
      BLOCK "StringFileInfo"
      BEGIN
        BLOCK "040904E4"
        BEGIN
          VALUE "CompanyName",      stringize( VRC_COMPANYNAME )
          VALUE "FileDescription",  stringize( VRC_FILEDESCRIPTION )
          VALUE "FileVersion",      stringize( VRC_FILEVERSION )
          VALUE "LegalCopyright",   stringize( VRC_COPYRIGHT )
          VALUE "InternalName",     stringize( VRC_ORIGINALFILENAME )
          VALUE "OriginalFilename", stringize( VRC_ORIGINALFILENAME )
          VALUE "ProductName",      stringize( VRC_PRODUCTNAME )
          VALUE "ProductVersion",   stringize( VRC_PRODUCTVERSION )
        END
      END
      BLOCK "VarFileInfo"
      BEGIN
        VALUE "Translation", 0x409, 1200
      END
    END