自:http://hi.baidu.com/comeon010/blog/item/67c5669bfa759eb8c8eaf42a.html
SVN是当前比较流行的版本控制软件,下面主要介绍通过SVN在程序编译时自动生成版本号。
基本思想:利用SubWCRev.exe获取版本信息,读入屏幕流,生成包括版本号信息的“.H文件”,并修改“.rc资源文件”中的版本信息,“.H文件”主要用于关于框中的版本显示,简单格式如下:
#ifndef __SVN_VERSION_MAX
#define __SVN_VERSION_MAX XXX
#endif
用下面附录的源码编译SVNVersionGen.exe
使用说明:
建立一个批处理文件
setlocal
设置TortoiseSVN安装目录SVNVersionGen -HEADER "%SVN_PATH%" "%WORK_DIR%" "SVNVersion.h"
设置子项目名称
set PRO1_NAME=PROJECT1
SVNVersionGen -RESVERSION "%SVN_PATH%" "%WORK_DIR%\%PRO1_NAME%" "%WORK_DIR%\%PRO1_NAME%\%PRO1_NAME%.rc" %VERSION_M% %VERSION_S%
设置子项目2名称
set PRO1_NAME=PROJECT2
SVNVersionGen -RESVERSION "%SVN_PATH%" "%WORK_DIR%\%PRO1_NAME%" "%WORK_DIR%\%PRO1_NAME%\%PRO1_NAME%.rc" %VERSION_M% %VERSION_S%
endlocal
源码:
// SVNVersionGen.cpp
#include "stdafx.h"
#include<string>
#include<windows.h>
#include<iostream>
using namespace std;
int GetSVNVersion( const char* pProPath,const char* pWorkDir,int& nVer,string& strOut )
{
nVer = 0;
string strInfo;
SECURITY_ATTRIBUTES sa;
HANDLE hRead,hWrite;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead,&hWrite,&sa,0))
{
return -1;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
char strPro[MAX_PATH];
sprintf( strPro,"%s\\SubWCRev.exe \"%s\"",pProPath,pWorkDir );
if (!CreateProcess(NULL,strPro,NULL,NULL,TRUE,NULL,NULL,NULL,&si,&pi))
{
return -1;
}
CloseHandle(hWrite);
char buffer[4096] = {0};
DWORD bytesRead;
while(true)
{
if(ReadFile(hRead,buffer,4095,&bytesRead,NULL) == NULL)
break;
strInfo += buffer;
Sleep(200);
}
char strCon[4096];
strcpy( strCon,"SubWCRev: '" );
strcat( strCon,pWorkDir );
strcat( strCon,"'\nLast committed at revision %d\n" );
sscanf( strInfo.c_str(),strCon,&nVer);
int nn = 0;
for( int i =0;i<strInfo.length();i++ )
{
if( strInfo[i] == '\n' )
{
nn++;
continue;
}
if( nn >= 3 )
{
break;
}
if( nn >= 2 )
{
if( strInfo[i] != '\r' )
strOut.push_back(strInfo[i]);
}
}
return 0;
}
int main(int argc, char* argv[])
{
if( argc < 2 )
{
return 0;
}
if( strcmp(argv[1],"-HEADER")==0 )
{
if( argc <= 4 )
{
return 0;
}
int nVer = 0;
string strOut;
GetSVNVersion( argv[2],argv[3],nVer,strOut );
cout<<nVer<<endl;
if( nVer > 0 )
{
FILE* f = fopen( argv[4],"w" );
if( f )
{
fprintf( f,"#ifndef __SVN_VERSION_MAX\n" );
fprintf( f,"#define __SVN_VERSION_MAX %d\n",nVer+1 );
fprintf( f,"static const int __SVN_VERSION = %d;\n",nVer+1 );
fprintf( f,"#endif\n" );
fclose(f);
MessageBox(0,"成功生成版本头文件","",0);
}
}
else
{
MessageBox(0,"生成版本头文件失败","",0);
}
return 0;
}
if( strcmp(argv[1],"-RESVERSION")==0 )
{
if( argc <= 6 )
{
MessageBox(0,"更新资源文件版本号失败","",0);
return 0;
}
int nVer = 0;
string strOut;
GetSVNVersion( argv[2],argv[3],nVer,strOut );
//MessageBox(0,strOut.c_str(),"",0);
if( nVer <= 0 )
{
MessageBox(0,argv[4],"更新资源文件版本号失败",0);
return 0;
}
nVer ++;