Win32 使用生成事件,将项目版本号自动加一

举报
福州司马懿 发表于 2022/11/20 17:57:17 2022/11/20
【摘要】 预处理器定义在解决方案资源管理器视图,右击项目,选择属性。然后依次选择 C/C++ ——> 预处理器 ——> 预处理器定义,然后点击右边向下的三角形箭头,选择编辑在预处理器定义对话框中,点击“宏”按钮右侧面板,即是所有宏定义了。例如,项目名称叫$(ProjectName) 生成前事件首先创建一个version.py文件,放在项目目录下version.py输入如下内容,作用是打印所有传入的参...

预处理器定义

在解决方案资源管理器视图,右击项目,选择属性。然后依次选择 C/C++ ——> 预处理器 ——> 预处理器定义,然后点击右边向下的三角形箭头,选择编辑

图片.png

在预处理器定义对话框中,点击“宏”按钮

图片.png

右侧面板,即是所有宏定义了。例如,项目名称叫$(ProjectName)

图片.png

生成前事件

首先创建一个version.py文件,放在项目目录下
图片.png

version.py输入如下内容,作用是打印所有传入的参数

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import sys
import re
import os


if __name__ == "__main__":
  argc = len(sys.argv)
  if(argc > 0):
    print(sys.argv)

生成前事件,指的是生成dll或exe之前,要执行的命令行。说明是该命令行的注释,会先被打印出来,然后再执行命令行输出其打印内容。这里,我们分别填入如下内容

命令行:python version.py $(ProjectName).rc
说明:获取版本号

然后右击项目,选择生成。可以看到,在输出面板中,先打印了说明的内容,然后才执行命令行
图片.png

版本号递增

版本号递增的测试程序如下,保存为version2.py

import re
from functools import reduce
from itertools import accumulate

def get_next_version(data) -> str:
    if not data:
        return ''
    if re.search(r'(?i)[a-z]', data):
        return data
    mylist = re.split(r'\.', data)    # 使用 . 号分隔
    mylen = [len(i) for i in mylist]  # 每个值有几位数
    mydata = str(int(reduce(lambda x, y: x + y, mylist)) + 1)  # 总位数 + 1

    result = ''
    start_index = 0

    if len(mydata) != sum(mylen):
        mylen[0] += 1

    for i in accumulate(mylen):
        result += mydata[start_index:i] + '.'
        start_index = i

    return result.rstrip('.')


if __name__ == '__main__':
    print(get_next_version('2.3.6'))          # 2.3.7
    print(get_next_version('1.2.3.1777.9'))   # 1.2.3.1778.0
    print(get_next_version('1.2.3.1777.09'))  # 1.2.3.1777.10
    print(get_next_version('9.99.999.9999'))  # 10.00.000.0000

执行python version.py可以看到版本号递增结果
图片.png

获取当前版本号

将下面代码保存为 version3.py 执行 python version3.py 命令,提取文件版本FileVersion

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import sys
import re
import os

#打开文件
def open_file(fileName, flag):
    try:
        f = open(fileName, flag, encoding='utf-16-le')
        return f
    except BaseException:
        return None
    return None

#提取文件版本号
def extra_version(fileName):
    versionFile = open_file(fileName, 'r')
    if not versionFile:
        print('文件打开失败')
        return None;
    verStr = None
    for line in versionFile.readlines():
        if -1 != line.find('FileVersion'):
            print(line)
            verArr = re.findall('\d+\.\d+\.\d+\.\d+', line)
            if(len(verArr) > 0):
                verStr = verArr[0]
                print(verStr)
                return verStr

#主函数
if __name__ == "__main__":
    argc = len(sys.argv)
    if(argc > 0):
        print(sys.argv)
        extra_version(sys.argv[1])

编写自动替换脚本

经过上门铺垫,大部分代码逻辑也已经写明。现在要做的就是替换版本号了

首先,先将 $(ProjectName).rc 文件中的4个版本号改为一致的,例如

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

VS_VERSION_INFO VERSIONINFO
 FILEVERSION 1,0,0,1
 PRODUCTVERSION 1,0,0,1
 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", "TODO: <公司名>"
            VALUE "FileDescription", "TODO: <文件说明>"
            VALUE "FileVersion", "1.0.0.1"
            VALUE "InternalName", "ShapedWi.exe"
            VALUE "LegalCopyright", "Copyright (C) 2022"
            VALUE "OriginalFilename", "ShapedWi.exe"
            VALUE "ProductName", "TODO: <产品名>"
            VALUE "ProductVersion", "1.0.0.1"
        END
    END
    BLOCK "VarFileInfo"
    BEGIN
        VALUE "Translation", 0x804, 1200
    END
END

然后修改 version.py(前面已设置过“生成前事件”),修改为如下内容

#!/usr/bin/python
# -*- coding: UTF-8 -*-
import sys
import re
import os
from functools import reduce
from itertools import accumulate

#版本号递增
def get_next_version(data) -> str:
    if not data:
        return ''
    if re.search(r'(?i)[a-z]', data):
        return data
    mylist = re.split(r'\.', data)    # 使用 . 号分隔
    mylen = [len(i) for i in mylist]  # 每个值有几位数
    mydata = str(int(reduce(lambda x, y: x + y, mylist)) + 1)  # 总位数 + 1

    result = ''
    start_index = 0

    if len(mydata) != sum(mylen):
        mylen[0] += 1

    for i in accumulate(mylen):
        result += mydata[start_index:i] + '.'
        start_index = i

    return result.rstrip('.')

#打开文件
def open_file(fileName, flag):
    try:
        f = open(fileName, flag, encoding='utf-16-le')
        return f
    except BaseException:
        return None
    return None

#提取文件版本号
def extra_version(src):
    srcFile = open_file(src, 'r')
    if not srcFile:
        print('src文件打开失败')
        return None;
    verStr = None
    for line in srcFile.readlines():
        if -1 != line.find('FileVersion'):
            print(line)
            verArr = re.findall('\d+\.\d+\.\d+\.\d+', line)
            if(len(verArr) > 0):
                verStr = verArr[0]
                return verStr

#写入输出文件
def replace_ver(src, dst, oldVer, newVer):
    srcFile = open_file(src, 'r')
    if not srcFile:
        print('src文件打开失败')
        return;
    dstFile = open_file(dst, 'w')
    if not dstFile:
        print('dst文件打开失败')
        return;
    oldDotVer = oldVer.replace('.', ',')
    newDotVer = newVer.replace('.', ',')
    for line in srcFile.readlines():
        line = line.replace(oldVer, newVer)
        line = line.replace(oldDotVer, newDotVer)
        dstFile.write(line)

#将输出文件覆盖回源文件
def os_swap(src, dst):
  try:
    os.rename(src, dst)
  except FileExistsError:
    os.remove(dst)
    os.rename(src, dst)

#主函数
if __name__ == "__main__":
    argc = len(sys.argv)
    if(argc > 0):
        print(sys.argv)
        src = sys.argv[1]
        dst = src + '.tmp'
        ver = extra_version(src)
        newVer = get_next_version(ver)
        print('version', ver, newVer)
        replace_ver(src, dst, ver, newVer)
        os_swap(dst, src)
        print('执行成功')

右击项目,然后生成。然后在打开生成的exe文件,查看其属性可以发现,修改时间和当前系统时间一致,且版本号也被加1了

图片.png

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。