自从有了版本控制,Coder 似乎就多了一剂后悔药,让人爽的不行。有时我们会需要在程序中嵌入程序的编译信息,比如,版本修订号、编译日期等,这些对于发行程序和黑盒测试都是很有用的,可以让我们快速定位到数个发行版中的准确版本或者BUG所在。
  这里就是介绍如何"自动"同步SVN和程序集的版本信息,Coding 的目的就是让 Coder 更懒。
  要完成这个工作,首先要安装 TortoiseSVN及 Subversion,并让你的项目处于 SVN 的版本控制之下。
  P.S : 这里推荐 TortoiseSVN 和 AnkhSVN 一起管理项目,TortoiseSVN 做常见任务,AnkhSVN 主要用于在IDE中跟踪状态。
  
  首先,我们需要 SubWCRev.exe,这是由 TortoiseSVN 提供的实用工具,可以获取工作拷贝或版本库的一些信息并通过模板替换。
  这里我写了一个类似于函数的 AutoRevision.bat 脚本来直接简化我们的工作。
   
AutoRevision.bat :
::<code>
::  
<revsion>$Rev: 4 $</revision>
::  
<owner name="Zealic" mail="rszealic@gmail.com" />
::
</code>
::
-----------------------------
::
<summary>
::  根据指定的 SVN 工作目录的信息和模板生成目标文件。
::
</summary>
::
<param name="workDir">要获取信息的 SVN 工作目录。</param>
::
<param name="template">模板文件路径。</param>
::
<param name="target">生成的目标文件路径。</param>
::
<returns>装载量</returns>
::
<remark>
::   当生成项目时 Visual Studio 如果已经打开 
%target% 参数指向的文件,那么可能导致模板替换更新不精确。
:: 导致该问题的原因是:SubWCRev.exe 修改了 
%target%,但是 VS 检测到了这一情况,会弹出对话框询问用户。
:: 必须重新加载才可以,否则 VS 将会编译未替换过的 
%target% 文件。
::
</remark>
::
=============================


::
-----------------------------
::
** Initialize
@ECHO OFF
SETLOCAL ENABLEEXTENSIONS
REM Initialize Constants
SET TSVN_INFO_FILE
=.\TSVN_INFO.tmp
REM Initialize script arguments
SET workDir
=%1
SET template
=%2
SET target
=%3

REM Goto main entry
GOTO MAIN
::
=============================


::
-----------------------------
::
** Main entry
:MAIN
pushd 
%workDir%
SET workDir
=.\

REM 检查参数
IF 
%workDir%=="" GOTO ARGUMENT_ERROR
IF 
%template%=="" GOTO ARGUMENT_ERROR
IF 
%target%=="" GOTO ARGUMENT_ERROR

REM 查询注册表
reg query HKLM\SOFTWARE\TortoiseSVN 
/v Directory > %TSVN_INFO_FILE% 2>NUL

REM 查找 TSVN 路径
FOR 
/"tokens=*" %%i IN (%TSVN_INFO_FILE%) DO (
  ECHO 
%%| find "Directory    REG_SZ" > NUL
  IF 
%ERRORLEVEL% == 0 (
    ECHO 
%%> %TSVN_INFO_FILE%
  )
)
SET 
/P TSVN_PATH= < %TSVN_INFO_FILE%
SET TSVN_PATH
=%TSVN_PATH:~23,-1%

REM 调用 TSVN 替换模板
IF NOT 
%ERRORLEVEL% == 0 GOTO UNKNOW_ERROR
"%TSVN_PATH%bin\SubWCRev.exe" %workDir% %template% %target%
IF NOT 
%ERRORLEVEL% == 0 GOTO UNKNOW_ERROR
GOTO SUCESSED
::
=============================


::
-----------------------------
::
** Error handlers

:ARGUMENT_ERROR
ECHO 传入的参数无效。
GOTO FAIL

:NOT_FOUND_TSVN
ECHO 查询TortoiseSVN 的安装信息失败。
GOTO FAIL

:UNKNOW_ERROR
ECHO 未知错误。
:FAIL
::
=============================

::
-----------------------------
::
** Program exit
:FAIL
DEL 
/%TSVN_INFO_FILE% 2>NUL
ECHO 模板替换失败。
popd
EXIT 
1

:SUCESSED
DEL 
/%TSVN_INFO_FILE% 2>NUL
ECHO 成功进行了模板替换。
popd
EXIT 
0
::
=============================

 
然后创建一个供脚本使用的模板 AssemblyInfo.tpl,内容如下:
AssemblyInfo.tpl
/**
<code>
  <revsion>$Rev$ </revision>
  <owner name="Zealic" mail="rszealic@gmail.com" />
</code>
*
*/

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

[assembly: AssemblyTitle(ThisAssembly.Title)]
[assembly: AssemblyDescription(ThisAssembly.Information)]
[assembly: AssemblyConfiguration(
"From Mars.")]
[assembly: AssemblyCompany(
"Google")]
[assembly: AssemblyCopyright(
"版权所有 (C) Baidu 2007")]
[assembly: AssemblyDefaultAlias(
"Live")]
[assembly: AssemblyProduct(
"RevTest")]
[assembly: AssemblyTrademark(
"Yahoo!")]
[assembly: AssemblyCulture(
"")]
[assembly: ComVisible(
false)]
[assembly: Guid(
"3FBDB8EE-61FB-46ef-8B61-CC28F46C08B9")]
[assembly: AssemblyVersion(ThisAssembly.Version)]
[assembly: AssemblyFileVersion(ThisAssembly.FileVersion)]

internal static class ThisAssembly
{
    
public const string Title = "RevTest";
    
public const string Version = "1.2.0." + Revision;
    
public const string FileVersion = Version;

    
public const string BuildTime = "$WCNOW$";
    
public const string Revision = "$WCREV$";
    
public const string RevisionRange = "$WCRANGE$";
    
public const string RevisionMixed = "$WCMIXED?True:False$";
    
public const string RevisionModified = "$WCMODS?True:False$";

    
public const string Information = "Name=" + Title + "\r\n"
#if DEBUG
 
+ "Build=DEBUG\r\n"
#elif RELEASE
        
+ "Build=RELEASE\r\n"
#else
        
+ "Build=UNKNOW\r\n"
#endif
 
+ "Revision=" + Revision + "\r\n"
        
+ "RevRange=" + RevisionRange + "\r\n"
        
+ "RevMixed=" + RevisionMixed + "\r\n"
        
+ "Modified=" + RevisionModified + "\r\n\r\n"
        
+ BuildTime + "\r\n";

}



  之后为项目添加预生成事件处理命令:
  在 属性->项目生成事件->预生成事件命令行 中键入如下代码 :
"$(ProjectDir)\Properties\AutoRevision.bat" "$(ProjectDir)" .\Properties\AssemblyInfo.tpl .\Properties\AssemblyInfo.cs


这样,程序就可以在每次编译的时候自动更新程序集信息了,我们可以在 <AssemblyFile>.exe->属性->版本->备注中看到如下信息:

Name=RevTest
Build
=DEBUG
Revision
=4
RevRange
=4
RevMixed
=False
Modified
=False

2007/12/05 19:00:35


示例工程下载 :  RevTest.rar

posted on 2007-12-05 19:30  Zealic  阅读(4155)  评论(8编辑  收藏  举报