1、setver 5改为setver=5
2、新增-setupd=n命令行参数,n=0表示使用inno setup,n=1表示使用nsis脚本,并自动设置脚本的版本号和自动运行脚本。
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
#include "gitver_tag.h"
|
#include "gitver_tag.h"
|
||||||
#include "gitver_types.h"
|
#include "gitver_types.h"
|
||||||
#include "gitver_version.h"
|
#include "gitver_version.h"
|
||||||
|
#include "gitver_setup.h"
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
#define new DEBUG_NEW
|
#define new DEBUG_NEW
|
||||||
@@ -353,18 +354,21 @@ void PrintFullUsageExamples()
|
|||||||
_T("用法:\n")
|
_T("用法:\n")
|
||||||
_T(" gitver (显示帮助后进入当前分支创建 tag 流程)\n")
|
_T(" gitver (显示帮助后进入当前分支创建 tag 流程)\n")
|
||||||
_T(" gitver rewrite [PEType可选]\n")
|
_T(" gitver rewrite [PEType可选]\n")
|
||||||
_T(" gitver setver [pid] [repoPath可选] [-test可选]\n")
|
_T(" gitver setver=<pid> [repoPath可选] [-f可选] [-test可选]\n")
|
||||||
_T(" gitver nuitkabuild [pid] [mainPy] [repoPath可选] [-test可选] [nuitka额外参数可选]\n")
|
_T(" gitver nuitkabuild [pid] [mainPy] [repoPath可选] [-test可选] [nuitka额外参数可选]\n")
|
||||||
_T(" gitver nuitkapydbuild [pid] [modulePy] [repoPath可选] [-test可选] [nuitka额外参数可选]\n")
|
_T(" gitver nuitkapydbuild [pid] [modulePy] [repoPath可选] [-test可选] [nuitka额外参数可选]\n")
|
||||||
|
_T(" gitver -setup=0|1 [pid] [repoPath可选] [-f可选] [-test可选]\n")
|
||||||
|
_T(" -setup=0: 使用 Inno Setup 脚本 (setup.iss)\n")
|
||||||
|
_T(" -setup=1: 使用 NSIS 脚本 (setup.nsh)\n")
|
||||||
_T("\n示例:\n")
|
_T("\n示例:\n")
|
||||||
_T(" gitver\n")
|
_T(" gitver\n")
|
||||||
_T(" gitver rewrite\n")
|
_T(" gitver rewrite\n")
|
||||||
_T(" gitver rewrite 2\n")
|
_T(" gitver rewrite 2\n")
|
||||||
_T(" gitver rewrite -f\n")
|
_T(" gitver rewrite -f\n")
|
||||||
_T(" gitver setver 5 E:\\Code\\OTH\\gitver\n")
|
_T(" gitver setver=5 E:\\Code\\OTH\\gitver\n")
|
||||||
_T(" gitver setver 5\n")
|
_T(" gitver setver=5\n")
|
||||||
_T(" gitver setver 5 -f\n")
|
_T(" gitver setver=5 -f\n")
|
||||||
_T(" gitver setver 5 -test\n")
|
_T(" gitver setver=5 -test\n")
|
||||||
_T(" gitver nuitkabuild 5 main.py\n")
|
_T(" gitver nuitkabuild 5 main.py\n")
|
||||||
_T(" gitver nuitkabuild 5 main.py -f\n")
|
_T(" gitver nuitkabuild 5 main.py -f\n")
|
||||||
_T(" gitver nuitkabuild 5 main.py -test\n")
|
_T(" gitver nuitkabuild 5 main.py -test\n")
|
||||||
@@ -374,6 +378,8 @@ void PrintFullUsageExamples()
|
|||||||
_T(" gitver nuitkapydbuild 5 module.py -f\n")
|
_T(" gitver nuitkapydbuild 5 module.py -f\n")
|
||||||
_T(" gitver nuitkapydbuild 5 module.py -test\n")
|
_T(" gitver nuitkapydbuild 5 module.py -test\n")
|
||||||
_T(" gitver nuitkapydbuild 5 src\\core.py E:\\Code\\MyPyProj --output-dir=dist\n")
|
_T(" gitver nuitkapydbuild 5 src\\core.py E:\\Code\\MyPyProj --output-dir=dist\n")
|
||||||
|
_T(" gitver -setup=0 5\n")
|
||||||
|
_T(" gitver -setup=1 5 E:\\Code\\MyProj\n")
|
||||||
_T("\n说明: nuitkabuild/nuitkapydbuild 中,-f/-test 在额外参数开始前表示 gitver 选项;进入额外参数后会透传给 Nuitka。\n")
|
_T("\n说明: nuitkabuild/nuitkapydbuild 中,-f/-test 在额外参数开始前表示 gitver 选项;进入额外参数后会透传给 Nuitka。\n")
|
||||||
_T("-test: 将产品版本号的 major 和 minor 都置为 0(用于测试版本构建)。\n")
|
_T("-test: 将产品版本号的 major 和 minor 都置为 0(用于测试版本构建)。\n")
|
||||||
_T("无参数时会读取当前分支最近三次 tag,并提示选择 major 加 1 或 minor 加 1,然后创建新 tag。\n");
|
_T("无参数时会读取当前分支最近三次 tag,并提示选择 major 加 1 或 minor 加 1,然后创建新 tag。\n");
|
||||||
@@ -387,7 +393,7 @@ void PrintFullUsageExamples()
|
|||||||
void PrintShortCommandUsage()
|
void PrintShortCommandUsage()
|
||||||
{
|
{
|
||||||
_tprintf(_T("请使用:gitver rewrite [PE类型可选]\n"));
|
_tprintf(_T("请使用:gitver rewrite [PE类型可选]\n"));
|
||||||
_tprintf(_T("请使用:gitver setver [pid] [repoPath可选]\n"));
|
_tprintf(_T("请使用:gitver setver=<pid> [repoPath可选]\n"));
|
||||||
_tprintf(_T("或:gitver nuitkabuild [pid] [mainPy] [repoPath可选] [nuitka额外参数可选]\n"));
|
_tprintf(_T("或:gitver nuitkabuild [pid] [mainPy] [repoPath可选] [nuitka额外参数可选]\n"));
|
||||||
_tprintf(_T("或:gitver nuitkapydbuild [pid] [modulePy] [repoPath可选] [nuitka额外参数可选]\n"));
|
_tprintf(_T("或:gitver nuitkapydbuild [pid] [modulePy] [repoPath可选] [nuitka额外参数可选]\n"));
|
||||||
}
|
}
|
||||||
@@ -476,6 +482,14 @@ LPCTSTR GetExitCodeHint(int nRetCode)
|
|||||||
return _T("interactive: verify tag failed");
|
return _T("interactive: verify tag failed");
|
||||||
case 35:
|
case 35:
|
||||||
return _T("rewrite version file failed");
|
return _T("rewrite version file failed");
|
||||||
|
case 36:
|
||||||
|
return _T("setup: unsupported -setup value");
|
||||||
|
case 37:
|
||||||
|
return _T("setup: setup script not found");
|
||||||
|
case 38:
|
||||||
|
return _T("setup: modify setup script failed");
|
||||||
|
case 39:
|
||||||
|
return _T("setup: compiler not found");
|
||||||
default:
|
default:
|
||||||
return _T("");
|
return _T("");
|
||||||
}
|
}
|
||||||
@@ -559,28 +573,19 @@ void GetDirInfo()
|
|||||||
/// <returns>返回值。</returns>
|
/// <returns>返回值。</returns>
|
||||||
int HandleSetVerCommand(int argc, TCHAR* argv[])
|
int HandleSetVerCommand(int argc, TCHAR* argv[])
|
||||||
{
|
{
|
||||||
if (argc < 3)
|
// 解析 "setver=N" 中的 pid
|
||||||
{
|
CString strPid = CString(argv[1]).Mid(7); // 跳过 "setver="
|
||||||
_tprintf(_T("错误: 参数不足。\n"));
|
|
||||||
PrintCommandUsageAndExamples(_T("setver"), _T("[pid]"), _T(""));
|
|
||||||
_tprintf(_T("参数说明:\n"));
|
|
||||||
_tprintf(_T(" pid: 产品ID,必填,范围0-65535。\n"));
|
|
||||||
_tprintf(_T(" repoPath: 仓库路径,可选,默认使用当前目录。\n"));
|
|
||||||
|
|
||||||
return 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
UINT nPid = 0;
|
UINT nPid = 0;
|
||||||
int nArgRet = ParseUInt16ArgOrError(argv, 2, _T("pid"), nPid, 4);
|
if (strPid.IsEmpty() || !TryParseUInt16(strPid, nPid))
|
||||||
if (nArgRet != 0)
|
|
||||||
{
|
{
|
||||||
return nArgRet;
|
_tprintf(_T("错误: setver= 后的 pid 无效:%s,应为 0-65535 范围的整数。\n"), strPid.GetString());
|
||||||
|
return 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPCTSTR lpRepoPath = NULL;
|
LPCTSTR lpRepoPath = NULL;
|
||||||
BOOL bUseDefaultTagWhenMissing = FALSE;
|
BOOL bUseDefaultTagWhenMissing = FALSE;
|
||||||
BOOL bTestMode = FALSE;
|
BOOL bTestMode = FALSE;
|
||||||
int nRepoArgRet = ParseSetVerOptions(argc, argv, lpRepoPath, bUseDefaultTagWhenMissing, bTestMode);
|
int nRepoArgRet = ParseSetVerOptions(argc, argv, 2, lpRepoPath, bUseDefaultTagWhenMissing, bTestMode);
|
||||||
if (nRepoArgRet != 0)
|
if (nRepoArgRet != 0)
|
||||||
{
|
{
|
||||||
return nRepoArgRet;
|
return nRepoArgRet;
|
||||||
@@ -617,6 +622,35 @@ int HandleSetVerCommand(int argc, TCHAR* argv[])
|
|||||||
_tprintf(_T("ProductVersion=%s\n"), strProductVersion.GetString());
|
_tprintf(_T("ProductVersion=%s\n"), strProductVersion.GetString());
|
||||||
_tprintf(_T("FileVersion=%s\n"), strFileVersion.GetString());
|
_tprintf(_T("FileVersion=%s\n"), strFileVersion.GetString());
|
||||||
|
|
||||||
|
// 检查是否附带了 -setup=N 标志
|
||||||
|
int nSetupType = -1;
|
||||||
|
for (int i = 2; i < argc; ++i)
|
||||||
|
{
|
||||||
|
CString strArg = argv[i];
|
||||||
|
if (strArg.GetLength() > 7 && strArg.Left(7).CompareNoCase(_T("-setup=")) == 0)
|
||||||
|
{
|
||||||
|
UINT nVal = 0;
|
||||||
|
if (!TryParseUInt16(strArg.Mid(7), nVal) || (nVal != 0 && nVal != 1))
|
||||||
|
{
|
||||||
|
_tprintf(_T("错误: -setup 参数值 \"%s\" 不支持,仅支持 0(Inno Setup)或 1(NSIS)。\n"),
|
||||||
|
strArg.Mid(7).GetString());
|
||||||
|
return 36;
|
||||||
|
}
|
||||||
|
nSetupType = (int)nVal;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nSetupType >= 0)
|
||||||
|
{
|
||||||
|
// -setup=N 存在:不回写版本信息到项目文件,只修改安装脚本并编译
|
||||||
|
if (!ExecuteSetupBuild(nSetupType, strProductVersion))
|
||||||
|
{
|
||||||
|
return 38;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return RewriteSetVerByProjectType(lpRepoPath, strProductVersion, strFileVersion);
|
return RewriteSetVerByProjectType(lpRepoPath, strProductVersion, strFileVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -857,7 +891,7 @@ int main(int argc, TCHAR* argv[], TCHAR* envp[])
|
|||||||
return nCmdRet;
|
return nCmdRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (argc >= 2 && _tcsicmp(argv[1], _T("setver")) == 0)
|
if (argc >= 2 && _tcsnicmp(argv[1], _T("setver="), 7) == 0)
|
||||||
{
|
{
|
||||||
DWORD dwStartTick = LogCommandStart(_T("setver"));
|
DWORD dwStartTick = LogCommandStart(_T("setver"));
|
||||||
int nCmdRet = HandleSetVerCommand(argc, argv);
|
int nCmdRet = HandleSetVerCommand(argc, argv);
|
||||||
@@ -875,6 +909,15 @@ int main(int argc, TCHAR* argv[], TCHAR* envp[])
|
|||||||
return nCmdRet;
|
return nCmdRet;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (argc >= 2 && _tcsnicmp(argv[1], _T("-setup="), 7) == 0)
|
||||||
|
{
|
||||||
|
DWORD dwStartTick = LogCommandStart(_T("-setup"));
|
||||||
|
int nCmdRet = HandleSetupCommand(argc, argv);
|
||||||
|
LogCommandEnd(_T("-setup"), dwStartTick, nCmdRet);
|
||||||
|
PrintCommandFailedWithCode(_T("-setup"), nCmdRet);
|
||||||
|
return nCmdRet;
|
||||||
|
}
|
||||||
|
|
||||||
_tprintf(_T("错误:未知命令:%s\n"), argv[1]);
|
_tprintf(_T("错误:未知命令:%s\n"), argv[1]);
|
||||||
PrintShortCommandUsage();
|
PrintShortCommandUsage();
|
||||||
|
|
||||||
|
|||||||
@@ -151,6 +151,7 @@
|
|||||||
<ClInclude Include="GitVer_nuitka.h" />
|
<ClInclude Include="GitVer_nuitka.h" />
|
||||||
<ClInclude Include="GitVer_process.h" />
|
<ClInclude Include="GitVer_process.h" />
|
||||||
<ClInclude Include="GitVer_rewrite.h" />
|
<ClInclude Include="GitVer_rewrite.h" />
|
||||||
|
<ClInclude Include="GitVer_setup.h" />
|
||||||
<ClInclude Include="GitVer_tag.h" />
|
<ClInclude Include="GitVer_tag.h" />
|
||||||
<ClInclude Include="GitVer_types.h" />
|
<ClInclude Include="GitVer_types.h" />
|
||||||
<ClInclude Include="GitVer_version.h" />
|
<ClInclude Include="GitVer_version.h" />
|
||||||
@@ -165,6 +166,7 @@
|
|||||||
<ClCompile Include="GitVer_nuitka.cpp" />
|
<ClCompile Include="GitVer_nuitka.cpp" />
|
||||||
<ClCompile Include="GitVer_process.cpp" />
|
<ClCompile Include="GitVer_process.cpp" />
|
||||||
<ClCompile Include="GitVer_rewrite.cpp" />
|
<ClCompile Include="GitVer_rewrite.cpp" />
|
||||||
|
<ClCompile Include="GitVer_setup.cpp" />
|
||||||
<ClCompile Include="GitVer_tag.cpp" />
|
<ClCompile Include="GitVer_tag.cpp" />
|
||||||
<ClCompile Include="GitVer_version.cpp" />
|
<ClCompile Include="GitVer_version.cpp" />
|
||||||
<ClCompile Include="pch.cpp">
|
<ClCompile Include="pch.cpp">
|
||||||
|
|||||||
@@ -10,13 +10,13 @@ void PrintInvalidRepoPathError(LPCTSTR lpRepoPath)
|
|||||||
_tprintf(_T("错误: 无效的仓库路径 %s\n"), lpRepoPath == NULL ? _T("<null>") : lpRepoPath);
|
_tprintf(_T("错误: 无效的仓库路径 %s\n"), lpRepoPath == NULL ? _T("<null>") : lpRepoPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
int ParseSetVerOptions(int argc, TCHAR* argv[], LPCTSTR& lpRepoPath, BOOL& bUseDefaultTagWhenMissing, BOOL& bTestMode)
|
int ParseSetVerOptions(int argc, TCHAR* argv[], int nStartIndex, LPCTSTR& lpRepoPath, BOOL& bUseDefaultTagWhenMissing, BOOL& bTestMode)
|
||||||
{
|
{
|
||||||
lpRepoPath = NULL;
|
lpRepoPath = NULL;
|
||||||
bUseDefaultTagWhenMissing = FALSE;
|
bUseDefaultTagWhenMissing = FALSE;
|
||||||
bTestMode = FALSE;
|
bTestMode = FALSE;
|
||||||
|
|
||||||
for (int i = 3; i < argc; ++i)
|
for (int i = nStartIndex; i < argc; ++i)
|
||||||
{
|
{
|
||||||
CString strArg = argv[i];
|
CString strArg = argv[i];
|
||||||
if (strArg.CompareNoCase(_T("-f")) == 0)
|
if (strArg.CompareNoCase(_T("-f")) == 0)
|
||||||
@@ -31,6 +31,12 @@ int ParseSetVerOptions(int argc, TCHAR* argv[], LPCTSTR& lpRepoPath, BOOL& bUseD
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -setup=N 由调用方单独处理,此处静默跳过
|
||||||
|
if (strArg.GetLength() > 7 && strArg.Left(7).CompareNoCase(_T("-setup=")) == 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (lpRepoPath == NULL)
|
if (lpRepoPath == NULL)
|
||||||
{
|
{
|
||||||
if (!PathIsDirectory(argv[i]))
|
if (!PathIsDirectory(argv[i]))
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
void PrintInvalidRepoPathError(LPCTSTR lpRepoPath);
|
void PrintInvalidRepoPathError(LPCTSTR lpRepoPath);
|
||||||
int ParseSetVerOptions(int argc, TCHAR* argv[], LPCTSTR& lpRepoPath, BOOL& bUseDefaultTagWhenMissing, BOOL& bTestMode);
|
int ParseSetVerOptions(int argc, TCHAR* argv[], int nStartIndex, LPCTSTR& lpRepoPath, BOOL& bUseDefaultTagWhenMissing, BOOL& bTestMode);
|
||||||
int ParseRewriteOptions(int argc, TCHAR* argv[], int& nPEType, BOOL& bForceRewrite);
|
int ParseRewriteOptions(int argc, TCHAR* argv[], int& nPEType, BOOL& bForceRewrite);
|
||||||
|
|||||||
396
GitVer/GitVer_setup.cpp
Normal file
396
GitVer/GitVer_setup.cpp
Normal file
@@ -0,0 +1,396 @@
|
|||||||
|
#include "pch.h"
|
||||||
|
#include "gitver.h"
|
||||||
|
#include "gitver_setup.h"
|
||||||
|
#include "gitver_common.h"
|
||||||
|
#include "gitver_cli.h"
|
||||||
|
#include "gitver_version.h"
|
||||||
|
#include "gitver_process.h"
|
||||||
|
|
||||||
|
extern TCHAR g_szCurModuleDir[MAX_PATH];
|
||||||
|
|
||||||
|
// 来自 gitver_rewrite.cpp / GitVer.cpp 的跨单元函数声明
|
||||||
|
std::string ToAnsiString(LPCTSTR lpText);
|
||||||
|
BOOL ReadTextFileAsAnsi(LPCTSTR lpFile, std::string& strContent, std::string& strBomPrefix);
|
||||||
|
BOOL WriteTextFileAsAnsi(LPCTSTR lpFile, const std::string& strContent, const std::string& strBomPrefix);
|
||||||
|
|
||||||
|
void PrintInvalidRepoPathError(LPCTSTR lpRepoPath);
|
||||||
|
int ParseSetVerOptions(int argc, TCHAR* argv[], LPCTSTR& lpRepoPath, BOOL& bUseDefaultTagWhenMissing, BOOL& bTestMode);
|
||||||
|
|
||||||
|
static const UINT DEFAULT_MAJOR_WHEN_NO_TAG_FOR_SETUP = 1;
|
||||||
|
static const UINT DEFAULT_MINOR_WHEN_NO_TAG_FOR_SETUP = 0;
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
// 内部工具:行级文本替换
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在字符串内容中查找首个包含 strToken 的整行,
|
||||||
|
/// 用 strNewLine 替换该行(不含行尾换行符)。
|
||||||
|
/// </summary>
|
||||||
|
static BOOL ReplaceLineByToken(std::string& strContent,
|
||||||
|
const std::string& strToken,
|
||||||
|
const std::string& strNewLine)
|
||||||
|
{
|
||||||
|
std::string::size_type nPos = strContent.find(strToken);
|
||||||
|
if (nPos == std::string::npos)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string::size_type nLineStart = strContent.rfind('\n', nPos);
|
||||||
|
nLineStart = (nLineStart == std::string::npos) ? 0 : (nLineStart + 1);
|
||||||
|
|
||||||
|
std::string::size_type nLineEnd = strContent.find('\n', nPos);
|
||||||
|
if (nLineEnd == std::string::npos)
|
||||||
|
{
|
||||||
|
nLineEnd = strContent.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 去掉可能存在的 \r
|
||||||
|
std::string::size_type nReplEnd = nLineEnd;
|
||||||
|
if (nReplEnd > nLineStart && strContent[nReplEnd - 1] == '\r')
|
||||||
|
{
|
||||||
|
--nReplEnd;
|
||||||
|
}
|
||||||
|
|
||||||
|
strContent.replace(nLineStart, nReplEnd - nLineStart, strNewLine);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
// 查找安装脚本
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 在 exe 所在目录及其上级目录中查找安装脚本。
|
||||||
|
/// nSetupType=0 查找 setup.iss,nSetupType=1 查找 setup.nsi。
|
||||||
|
/// </summary>
|
||||||
|
static BOOL FindSetupScript(int nSetupType, CString& strScriptPath)
|
||||||
|
{
|
||||||
|
strScriptPath.Empty();
|
||||||
|
|
||||||
|
LPCTSTR lpFileName = (nSetupType == 0) ? _T("setup.iss") : _T("setup.nsi");
|
||||||
|
|
||||||
|
// 当前 exe 目录(无末尾反斜杠)
|
||||||
|
CString strExeDir = g_szCurModuleDir;
|
||||||
|
|
||||||
|
// 尝试 exe 目录
|
||||||
|
CString strCandidate;
|
||||||
|
strCandidate.Format(_T("%s\\%s"), strExeDir.GetString(), lpFileName);
|
||||||
|
if (PathFileExists(strCandidate))
|
||||||
|
{
|
||||||
|
strScriptPath = strCandidate;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试上级目录
|
||||||
|
int nSlash = strExeDir.ReverseFind(_T('\\'));
|
||||||
|
if (nSlash > 0)
|
||||||
|
{
|
||||||
|
CString strParentDir = strExeDir.Left(nSlash);
|
||||||
|
strCandidate.Format(_T("%s\\%s"), strParentDir.GetString(), lpFileName);
|
||||||
|
if (PathFileExists(strCandidate))
|
||||||
|
{
|
||||||
|
strScriptPath = strCandidate;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
// 修改 Inno Setup 脚本
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改 .iss 脚本中的 AppVersion= 行。
|
||||||
|
/// </summary>
|
||||||
|
static BOOL ModifyIssScript(const CString& strScriptPath, const CString& strProductVersion)
|
||||||
|
{
|
||||||
|
std::string strContent;
|
||||||
|
std::string strBomPrefix;
|
||||||
|
if (!ReadTextFileAsAnsi(strScriptPath, strContent, strBomPrefix))
|
||||||
|
{
|
||||||
|
_tprintf(_T("错误: 读取 .iss 文件失败: %s\n"), strScriptPath.GetString());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string strToken = "AppVersion=";
|
||||||
|
if (strContent.find(strToken) == std::string::npos)
|
||||||
|
{
|
||||||
|
_tprintf(_T("错误: .iss 文件中未找到 AppVersion= 行: %s\n"), strScriptPath.GetString());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string strNewLine = "AppVersion=" + ToAnsiString(strProductVersion.GetString());
|
||||||
|
if (!ReplaceLineByToken(strContent, strToken, strNewLine))
|
||||||
|
{
|
||||||
|
_tprintf(_T("错误: 替换 .iss AppVersion= 行失败。\n"));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WriteTextFileAsAnsi(strScriptPath, strContent, strBomPrefix))
|
||||||
|
{
|
||||||
|
_tprintf(_T("错误: 写入 .iss 文件失败: %s\n"), strScriptPath.GetString());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_tprintf(_T("成功: 已更新 .iss AppVersion=%s\n"), strProductVersion.GetString());
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
// 修改 NSIS 脚本
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 修改 .nsh 脚本中的 !define PRODUCT_VERSION 行。
|
||||||
|
/// </summary>
|
||||||
|
static BOOL ModifyNshScript(const CString& strScriptPath, const CString& strProductVersion)
|
||||||
|
{
|
||||||
|
std::string strContent;
|
||||||
|
std::string strBomPrefix;
|
||||||
|
if (!ReadTextFileAsAnsi(strScriptPath, strContent, strBomPrefix))
|
||||||
|
{
|
||||||
|
_tprintf(_T("错误: 读取 .nsh 文件失败: %s\n"), strScriptPath.GetString());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string strToken = "!define PRODUCT_VERSION";
|
||||||
|
if (strContent.find(strToken) == std::string::npos)
|
||||||
|
{
|
||||||
|
_tprintf(_T("错误: .nsh 文件中未找到 !define PRODUCT_VERSION 行: %s\n"), strScriptPath.GetString());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string strNewLine = "!define PRODUCT_VERSION \"" + ToAnsiString(strProductVersion.GetString()) + "\"";
|
||||||
|
if (!ReplaceLineByToken(strContent, strToken, strNewLine))
|
||||||
|
{
|
||||||
|
_tprintf(_T("错误: 替换 .nsh PRODUCT_VERSION 行失败。\n"));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!WriteTextFileAsAnsi(strScriptPath, strContent, strBomPrefix))
|
||||||
|
{
|
||||||
|
_tprintf(_T("错误: 写入 .nsh 文件失败: %s\n"), strScriptPath.GetString());
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
_tprintf(_T("成功: 已更新 .nsh PRODUCT_VERSION=%s\n"), strProductVersion.GetString());
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
// 查找编译器
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找 Inno Setup 编译器 (ISCC.exe)。
|
||||||
|
/// 先查 PATH,再尝试常见安装路径。
|
||||||
|
/// </summary>
|
||||||
|
static CString FindInnoSetupCompiler()
|
||||||
|
{
|
||||||
|
TCHAR szPath[MAX_PATH] = { 0 };
|
||||||
|
if (::SearchPath(NULL, _T("ISCC.exe"), NULL, MAX_PATH, szPath, NULL) > 0)
|
||||||
|
{
|
||||||
|
return CString(szPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPCTSTR lpCandidates[] =
|
||||||
|
{
|
||||||
|
_T("C:\\Program Files (x86)\\Inno Setup 6\\ISCC.exe"),
|
||||||
|
_T("C:\\Program Files\\Inno Setup 6\\ISCC.exe"),
|
||||||
|
_T("C:\\Program Files (x86)\\Inno Setup 5\\ISCC.exe"),
|
||||||
|
_T("C:\\Program Files\\Inno Setup 5\\ISCC.exe"),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < _countof(lpCandidates); ++i)
|
||||||
|
{
|
||||||
|
if (PathFileExists(lpCandidates[i]))
|
||||||
|
{
|
||||||
|
return CString(lpCandidates[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找 NSIS 编译器 (makensis.exe)。
|
||||||
|
/// 先查 PATH,再尝试常见安装路径。
|
||||||
|
/// </summary>
|
||||||
|
static CString FindNsisCompiler()
|
||||||
|
{
|
||||||
|
TCHAR szPath[MAX_PATH] = { 0 };
|
||||||
|
if (::SearchPath(NULL, _T("makensis.exe"), NULL, MAX_PATH, szPath, NULL) > 0)
|
||||||
|
{
|
||||||
|
return CString(szPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
static LPCTSTR lpCandidates[] =
|
||||||
|
{
|
||||||
|
_T("C:\\Program Files (x86)\\NSIS\\makensis.exe"),
|
||||||
|
_T("C:\\Program Files\\NSIS\\makensis.exe"),
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < _countof(lpCandidates); ++i)
|
||||||
|
{
|
||||||
|
if (PathFileExists(lpCandidates[i]))
|
||||||
|
{
|
||||||
|
return CString(lpCandidates[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return CString();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
// 公共执行函数(供 HandleSetupCommand 和 setver -setup=N 共用)
|
||||||
|
// 不回写版本信息到项目文件,只修改安装脚本并调用编译器打包。
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
|
||||||
|
BOOL ExecuteSetupBuild(int nSetupType, const CString& strProductVersion)
|
||||||
|
{
|
||||||
|
// 查找安装脚本
|
||||||
|
CString strScriptPath;
|
||||||
|
if (!FindSetupScript(nSetupType, strScriptPath))
|
||||||
|
{
|
||||||
|
LPCTSTR lpScriptName = (nSetupType == 0) ? _T("setup.iss") : _T("setup.nsi");
|
||||||
|
_tprintf(_T("错误: 未在 exe 目录或上级目录中找到 %s。\n"), lpScriptName);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
_tprintf(_T("找到安装脚本: %s\n"), strScriptPath.GetString());
|
||||||
|
|
||||||
|
// 修改脚本中的版本号(不写回 .rc / AssemblyInfo.cs)
|
||||||
|
BOOL bModifyOk = (nSetupType == 0)
|
||||||
|
? ModifyIssScript(strScriptPath, strProductVersion)
|
||||||
|
: ModifyNshScript(strScriptPath, strProductVersion);
|
||||||
|
|
||||||
|
if (!bModifyOk)
|
||||||
|
{
|
||||||
|
_tprintf(_T("错误: 修改安装脚本版本信息失败。\n"));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查找编译器
|
||||||
|
CString strCompiler = (nSetupType == 0)
|
||||||
|
? FindInnoSetupCompiler()
|
||||||
|
: FindNsisCompiler();
|
||||||
|
|
||||||
|
if (strCompiler.IsEmpty())
|
||||||
|
{
|
||||||
|
LPCTSTR lpCompilerName = (nSetupType == 0)
|
||||||
|
? _T("ISCC.exe (Inno Setup)")
|
||||||
|
: _T("makensis.exe (NSIS)");
|
||||||
|
_tprintf(_T("错误: 未找到安装包编译器 %s,请确认已安装并加入 PATH。\n"), lpCompilerName);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
_tprintf(_T("找到编译器: %s\n"), strCompiler.GetString());
|
||||||
|
|
||||||
|
// 取脚本所在目录作为工作目录
|
||||||
|
CString strScriptDir = strScriptPath;
|
||||||
|
int nSlash = strScriptDir.ReverseFind(_T('\\'));
|
||||||
|
if (nSlash >= 0)
|
||||||
|
{
|
||||||
|
strScriptDir = strScriptDir.Left(nSlash);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建并执行编译命令
|
||||||
|
CString strCmd;
|
||||||
|
strCmd.Format(_T("cmd /c %s %s"),
|
||||||
|
QuoteCmdArg(strCompiler).GetString(),
|
||||||
|
QuoteCmdArg(strScriptPath).GetString());
|
||||||
|
_tprintf(_T("执行编译: %s\n"), strCmd.GetString());
|
||||||
|
|
||||||
|
CString strOutput = StartProcess(NULL, strCmd.GetBuffer(), strScriptDir.GetString());
|
||||||
|
strCmd.ReleaseBuffer();
|
||||||
|
|
||||||
|
if (strOutput.IsEmpty())
|
||||||
|
{
|
||||||
|
_tprintf(_T("警告: 编译器无输出,可能执行失败。\n"));
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
// 独立命令入口(argv[1] 形如 "-setup=0")
|
||||||
|
// ─────────────────────────────────────────────
|
||||||
|
|
||||||
|
int HandleSetupCommand(int argc, TCHAR* argv[])
|
||||||
|
{
|
||||||
|
// 解析 -setup=n 中的 n
|
||||||
|
CString strSetupArg = argv[1];
|
||||||
|
CString strN = strSetupArg.Mid(7); // 跳过 "-setup="
|
||||||
|
UINT nSetupType = UINT(-1);
|
||||||
|
if (!TryParseUInt16(strN, nSetupType) || (nSetupType != 0 && nSetupType != 1))
|
||||||
|
{
|
||||||
|
_tprintf(_T("错误: -setup 参数值 \"%s\" 不支持,仅支持 0(Inno Setup)或 1(NSIS)。\n"),
|
||||||
|
strN.GetString());
|
||||||
|
return 36;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc < 3)
|
||||||
|
{
|
||||||
|
_tprintf(_T("错误: 参数不足。\n"));
|
||||||
|
_tprintf(_T("用法:gitver -setup=0|1 [pid] [repoPath可选]\n"));
|
||||||
|
_tprintf(_T("示例:gitver -setup=0 5\n"));
|
||||||
|
_tprintf(_T("示例:gitver -setup=1 5 E:\\Code\\MyProj\n"));
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT nPid = 0;
|
||||||
|
int nArgRet = ParseUInt16ArgOrError(argv, 2, _T("pid"), nPid, 4);
|
||||||
|
if (nArgRet != 0)
|
||||||
|
{
|
||||||
|
return nArgRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
LPCTSTR lpRepoPath = NULL;
|
||||||
|
BOOL bUseDefaultTagWhenMissing = FALSE;
|
||||||
|
BOOL bTestMode = FALSE;
|
||||||
|
int nRepoArgRet = ParseSetVerOptions(argc, argv, 3, lpRepoPath, bUseDefaultTagWhenMissing, bTestMode);
|
||||||
|
if (nRepoArgRet != 0)
|
||||||
|
{
|
||||||
|
return nRepoArgRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
CString strProductVersion;
|
||||||
|
CString strFileVersion;
|
||||||
|
VersionBuildErrorCodes errorCodes = { 5, 6, 9 };
|
||||||
|
int nVersionRet = BuildVersionsFromRepo(
|
||||||
|
lpRepoPath,
|
||||||
|
nPid,
|
||||||
|
errorCodes,
|
||||||
|
strProductVersion,
|
||||||
|
strFileVersion,
|
||||||
|
bUseDefaultTagWhenMissing,
|
||||||
|
DEFAULT_MAJOR_WHEN_NO_TAG_FOR_SETUP,
|
||||||
|
DEFAULT_MINOR_WHEN_NO_TAG_FOR_SETUP);
|
||||||
|
if (nVersionRet != 0)
|
||||||
|
{
|
||||||
|
return nVersionRet;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bTestMode)
|
||||||
|
{
|
||||||
|
int nDot1 = strProductVersion.Find(_T('.'));
|
||||||
|
int nDot2 = (nDot1 >= 0) ? strProductVersion.Find(_T('.'), nDot1 + 1) : -1;
|
||||||
|
if (nDot2 > nDot1)
|
||||||
|
{
|
||||||
|
strProductVersion = strProductVersion.Left(nDot2 + 1) + _T("0.0");
|
||||||
|
}
|
||||||
|
_tprintf(_T("[test] 已将 major/minor 置零: ProductVersion=%s\n"), strProductVersion.GetString());
|
||||||
|
}
|
||||||
|
|
||||||
|
_tprintf(_T("ProductVersion=%s\n"), strProductVersion.GetString());
|
||||||
|
|
||||||
|
// 不回写版本信息到项目文件,直接修改安装脚本并编译打包
|
||||||
|
if (!ExecuteSetupBuild((int)nSetupType, strProductVersion))
|
||||||
|
{
|
||||||
|
return 38;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
16
GitVer/GitVer_setup.h
Normal file
16
GitVer/GitVer_setup.h
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 查找安装脚本、修改版本号并调用编译器打包。
|
||||||
|
/// nSetupType=0: Inno Setup (.iss);nSetupType=1: NSIS (.nsi)。
|
||||||
|
/// 不写回项目版本文件(.rc / AssemblyInfo.cs)。
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>TRUE 成功;FALSE 失败(错误已打印)。</returns>
|
||||||
|
BOOL ExecuteSetupBuild(int nSetupType, const CString& strProductVersion);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 处理独立的 -setup=n 命令行入口。
|
||||||
|
/// 退出码:0 成功,36 -setup 值不支持,37 未找到脚本,
|
||||||
|
/// 38 修改脚本失败,39 未找到编译器,其他同通用错误码。
|
||||||
|
/// </summary>
|
||||||
|
int HandleSetupCommand(int argc, TCHAR* argv[]);
|
||||||
Reference in New Issue
Block a user