1. 程式人生 > >持續整合之編譯後的.exe檔案自動帶有版本資訊(SVN Revision)

持續整合之編譯後的.exe檔案自動帶有版本資訊(SVN Revision)

       在最近的整合過程中,發現.exe可執行程式沒有帶版本資訊,對於要定位問題是比較難的。例如:測試人員在新拿到的版本發現問題,開發詢問版本號,這時測試人員就無處可尋了;又或者在新版本發現的問題要去舊版本驗證,沒有版本資訊就無法確定。

右擊.exe檔案選擇屬性--詳細資訊,如下:

可發現,沒有任何版本資訊。接下去,我把如何在每次編譯時關聯SVN版本號記錄到.exe檔案中分享給大家。

先看最終的效果:

這裡就顯示版本與產品資訊,其中“260”是SVN的版本號。

---------------------------------------------------------------------------------------------------

好了,我們來說重點:

編譯的是C++專案,首先要準備兩個檔案:“generate_version.py”,“StoneGeniu2.0.rc”

其中“generate_version.py”是我們要編寫的指令碼;

“StoneGeniu2.0.rc”是專案的資原始檔,可在專案檔案下搜到,備份一份。

這兩個檔案都放於專案資料夾的根目錄,對了這個專案資料夾得是加入版本控制。

先來看python指令碼內容:

import time
import os
import re
import subprocess

# 獲取SVN版本號
os.system("svn update")    #更新專案資料夾
os.system("svn info > info.txt")    #生成info.txt
info_fp = open("info.txt", "r")    #開啟info.txt
info_fp.seek(0, 2)   # 定位到檔案末尾
info_len = info_fp.tell()  # 獲取檔案大小
info_fp.seek(0, 0)
info_data = info_fp.read(info_len)
ret = re.search(r'Revision.+(\d{3})', info_data)
version_svn = ret.group(1)

version_date = time.strftime("%y%m%d", time.localtime(time.time()))
version_date2 = time.strftime("%m%d", time.localtime(time.time()))
version_format = "2.0"
version_format2 = "1,0,0,$svn"
version_string = version_format.replace("$date", version_date)
version_string = version_string.replace("$svn", version_svn)
version_file = version_format2.replace("$date", version_date2)
version_file = version_file.replace("$svn", version_svn)

print("%s" %version_string)
print("%s" %version_file)

# 開啟指定的rc檔案模板
rc = open("StoneGeniu2.0.rc", "a+", encoding="utf-16")
rc.seek(0, 2)   # 定位到檔案末尾
length = rc.tell()  # 獲取檔案大小
rc.seek(0, 0)

data = rc.read(length)
data = data.replace("$VERSION", version_string)
data = data.replace("$FILEVERSION", version_file)
# 儲存到指定的路徑
rc = open("./StoneGeniu2.0/StoneGeniu2.0.rc", "w", encoding='utf-16')
rc.truncate(0)
rc.write(data)
rc.flush()

再來,StoneGeniu2.0.rc

// Microsoft Visual C++ generated resource script.
//
#include "resource.h"

#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "winres.h"

/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS

/////////////////////////////////////////////////////////////////////////////
// 中文(簡體,中國) resources

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_CHS)
LANGUAGE LANG_CHINESE, SUBLANG_CHINESE_SIMPLIFIED

#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//

1 TEXTINCLUDE 
BEGIN
    "resource.h\0"
END

2 TEXTINCLUDE 
BEGIN
    "#include ""winres.h""\r\n"
    "\0"
END

3 TEXTINCLUDE 
BEGIN
    "\r\n"
    "\0"
END

#endif    // APSTUDIO_INVOKED


/////////////////////////////////////////////////////////////////////////////
//
// Icon
//

// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_ICON1               ICON                    "logo.ico"

/////////////////////////////////////////////////////////////////////////////
//
// Version
//

VS_VERSION_INFO VERSIONINFO
 FILEVERSION $FILEVERSION
 PRODUCTVERSION 1,2,0,0
 FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
 FILEFLAGS 0x1L
#else
 FILEFLAGS 0x0L
#endif
 FILEOS 0x40004L
 FILETYPE 0x1L
 FILESUBTYPE 0x0L
BEGIN
    BLOCK "StringFileInfo"
    BEGIN
        BLOCK "080404b0"
        BEGIN
            VALUE "CompanyName", "廈門XX科技股份有限公司"
            VALUE "FileDescription", ""
            VALUE "FileVersion", "$FILEVERSION"
            VALUE "InternalName", "StoneGeniu2.0.exe"
            VALUE "LegalCopyright", "Copyright (C) 2017"
            VALUE "OriginalFilename", "StoneGeniu2.0.exe"
            VALUE "ProductName", "石材精靈"
            VALUE "ProductVersion", "$VERSION"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x804, 1200
    END
END

#endif    // 中文(簡體,中國) resources
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//


/////////////////////////////////////////////////////////////////////////////
#endif    // not APSTUDIO_INVOKED

備註:這個檔案跟原檔案不同的在於,加入Version那部分的內容。

這兩個檔案都準備好後,執行“generate_version.py”  (這裡不懂怎麼執行的可百度);

執行後項目裡的StoneGeniu2.0.rc會被替換

最後用VS編譯專案後的.exe即帶有版本資訊。

       順帶說一句,因這個專案檔案是帶有版本控制的,剛被替換的StoneGeniu2.0.rc是與SVN上的有衝突,

我這裡可以先提交到SVN再編譯,如不懂SVN提交的可看我其他部落格。