自动修改某目录下符合条件的Delphi工程(dproj)版本号, 支持命令行调用
支持通配符忽略文件

-p [Path] 在[Path]路径下查询所有dproj文件(可以为空, 默认路径为程序当前路径)
-v [Version] 将查询到的dproj文件中Base节点版本改为[Version]并删除其他节点版本信息(可以为空, 进入程序后输入)
-i [File1,File2...]要忽略的文件, 支持? *的通配符, 忽略大小写, 包含路径, 不要包含扩展名, 如: work\project?
-b 修改时备份原文件到文件所在路径的dproj_bak目录下(默认不备份)
-ac 工作结束自动关闭程序(默认不关闭)

已经编译完的程序放CSDN了, 不过有点坑, 提交的资源不能修改内容, 也不能修改下载积分(当初没看, 直接选了5分...呵呵)

http://download.csdn.net/download/hskill/10120236

下面直接给出源码, 是个控制台程序

PS: 里面用到了QXML, 但是QXML会吧单引号转义, 不过不影响IDE的读取保存

program dproj_Version;

//  ***************************************************************************
//
// 版本: 1.0
// 作者: 刘志林
// 修改日期: 2017-11-15
// QQ: 17948876
// E-mail: lzl_17948876@hotmail.com
// 博客: http://www.cnblogs.com/lzl_17948876/
//
// !!! 若有修改,请通知作者,谢谢合作 !!!
//
// *************************************************************************** {$APPTYPE CONSOLE} {$R *.res} uses
System.SysUtils, System.Classes, System.IOUtils, System.Types, System.Masks,
QXML, QString; function _GetXNode(AXNParent: TQXMLNode; AName: string; out AValue: string): TQXMLNode;
begin
Result := AXNParent.ItemByName(AName);
if Result = nil then
Result := AXNParent.Add(AName);
AValue := Result.Text;
end; type
EInvalidVersion = Class(Exception); TVersion = record
public
procedure Init;
function IsEmpty: Boolean;
procedure FromString(AStr: string);
function ToString(ADelimiter: Char = '.'): string; case Integer of
: (Data: array[..] of UInt32);
: (MajorVer, MinorVer, Release, Build: UInt32);
end; { TVersion } procedure TVersion.FromString(AStr: string);
var
i: Integer;
begin
Init;
with TStringList.Create do
try
Delimiter := '.';
StrictDelimiter := True;
DelimitedText := AStr;
try
if Count <> then
Abort;
for i := to do
Data[i] := StrToInt(Strings[i]);
if IsEmpty then
Abort;
except
Init;
raise EInvalidVersion.Create(AStr + '不是有效的版本号');
end;
finally
Free;
end;
end; procedure TVersion.Init;
begin
MajorVer := ;
MinorVer := ;
Release := ;
Build := ;
end; function TVersion.IsEmpty: Boolean;
begin
Result := Data[] + Data[] + Data[] + Data[] = ;
end; function TVersion.ToString(ADelimiter: Char = '.'): string;
begin
Result := Format('%1:d%0:s%2:d%0:s%3:d%0:s%4:d', [ADelimiter, Data[], Data[], Data[], Data[]])
end; function _Compare(const AStr: string; const AL: array of string): Boolean;
var
i: Integer;
begin
Result := False;
for i := Low(AL) to High(AL) do
begin
if CompareText(AStr, AL[i]) <> then
Continue;
Result := True;
Break;
end;
end; function IsIgnored(AName: string; const AIGList: TArray<string>): Boolean;
var
i: Integer;
begin
Result := False;
for i := Low(AIGList) to High(AIGList) do
begin
if not MatchesMask(AName, AIGList[i]) then
Continue;
Result := True;
Break;
end;
end; const
_EXT = '.dproj'; const
Helps: array[..] of string = (
'-p [Path] 在[Path]路径下查询所有dproj文件(可以为空, 默认路径为程序当前路径)',
'-v [Version] 将查询到的dproj文件中Base节点版本改为[Version]并删除其他节点版本信息(可以为空, 进入程序后输入)',
'-i [File1,File2...]要忽略的文件, 支持? *的通配符, 忽略大小写, 包含路径, 不要包含扩展名, 如: work\project?',
'-b 修改时备份原文件到文件所在路径的dproj_bak目录下(默认不备份)',
'-ac 工作结束自动关闭程序(默认不关闭)'
); var
nXDOC: TQXML;
nXNRoot, nXN, nXNV: TQXMLNode;
l, i, nParamIndex, nFileIndex, nXNIndex, nIKIndex: Integer;
nStrs: TStringList;
nName, nVersionStr, nPath, nFile, nStr, nPK: string;
nIgnoredList: TArray<string>;
nVersion, nOldVersion: TVersion;
nFiles: TStringDynArray;
nBackup, nAutoClose: Boolean;
begin
try
{ TODO -oUser -cConsole Main : Insert code here }
ChDir(ExtractFilePath(ParamStr())); nPath := '.\';
nVersion.Init;
SetLength(nIgnoredList, );
nBackup := False;
nAutoClose := False; nParamIndex := ;
while nParamIndex <= ParamCount do
begin
nStr := ParamStr(nParamIndex); l := nStr.Length;
if not (nStr[] in ['-', '/']) then
Continue;
nStr := Copy(nStr, , l - ); if _Compare(nStr, ['p']) then {路径}
begin
nPath := ParamStr(nParamIndex + );
Inc(nParamIndex, );
end
else if _Compare(nStr, ['v']) then {版本号}
begin
nVersionStr := ParamStr(nParamIndex + );
Inc(nParamIndex, );
end
else if _Compare(nStr, ['i']) then {忽略的文件}
begin
with TStringList.Create do
try
StrictDelimiter := True;
Delimiter := ',';
DelimitedText := ParamStr(nParamIndex + );
SetLength(nIgnoredList, Count);
for i := to Count - do
nIgnoredList[i] := '*' + ChangeFileExt(Strings[i], '') + _EXT;
finally
Free;
end;
Inc(nParamIndex, );
end
else if _Compare(nStr, ['b']) then {备份}
begin
nBackup := True;
Inc(nParamIndex, );
end
else if _Compare(nStr, ['ac']) then {自动关闭}
begin
nAutoClose := True;
Inc(nParamIndex, );
end
else if _Compare(nStr, ['h', '?', 'help']) then {帮助}
begin
for i := Low(Helps) to High(Helps) do
Writeln(Helps[i]);
Abort;
end
else
Inc(nParamIndex, );
end; if nPath = '' then
raise Exception.Create('无效的路径');
nPath := TPath.GetFullPath(nPath);
if not DirectoryExists(nPath) then
raise Exception.CreateFmt('"%s" 路径不存在', [nPath]); if nVersionStr = '' then
Writeln('清输入版本号:')
else
try
nVersion.FromString(nVersionStr);
except
on E: Exception do
Writeln('错误: ' + E.Message);
end; while nVersion.IsEmpty do
begin
Write('> ');
Readln(nVersionStr);
try
nVersion.FromString(nVersionStr);
except
on E: Exception do
Writeln('错误: ' + E.Message);
end;
end; Writeln('');
Writeln('******** 开始处理 ********');
Writeln(Format('目标目录: %s', [nPath]));
Write('忽略的对象:');
for i := Low(nIgnoredList) to High(nIgnoredList) do
Write(Format(' "%s"', [nIgnoredList[i]]));
Write(#); nFiles := TDirectory.GetFiles(nPath, '*' + _EXT, TSearchOption.soAllDirectories); if Length(nFiles) = then
raise Exception.Create('待处理的文件数量为0'); Writeln(Format('待处理文件数量: %d', [Length(nFiles)]));
Writeln(''); nXDOC := TQXML.Create;
nStrs := TStringList.Create;
try
nStrs.Delimiter := ';';
nStrs.StrictDelimiter := True; for nFileIndex := Low(nFiles) to High(nFiles) do
begin
if IsIgnored(nFiles[nFileIndex], nIgnoredList) then
begin
Writeln('* 忽略 ' + nFiles[nFileIndex]);
Continue;
end; Writeln(nFiles[nFileIndex]);
try
nOldVersion.Init;
nXDOC.LoadFromFile(nFiles[nFileIndex]);
nXNRoot := nXDOC.Items[];
for nXNIndex := to nXNRoot.Count - do
begin
nXN := nXNRoot.Items[nXNIndex];
if nXN.Name <> 'PropertyGroup' then
Continue;
if nXN.Attrs.AsString['Condition'] = '''$(Base)''!=''''' then
begin
_GetXNode(nXN, 'VerInfo_MajorVer', nStr).Text := nVersion.MajorVer.ToString;
nOldVersion.MajorVer := StrToIntDef(nStr, );
_GetXNode(nXN, 'VerInfo_MinorVer', nStr).Text := nVersion.MinorVer.ToString;
nOldVersion.MinorVer := StrToIntDef(nStr, );
_GetXNode(nXN, 'VerInfo_Release', nStr).Text := nVersion.Release.ToString;
nOldVersion.Release := StrToIntDef(nStr, );
_GetXNode(nXN, 'VerInfo_Build', nStr).Text := nVersion.Build.ToString;
nOldVersion.Build := StrToIntDef(nStr, ); with _GetXNode(nXN, 'VerInfo_Keys', nStr) do
begin
nStrs.DelimitedText := Text;
for nIKIndex := to nStrs.Count - do
begin
nName := nStrs.KeyNames[nIKIndex];
if CompareText('FileVersion', nName) = then
nStrs[nIKIndex] := 'FileVersion=' + nVersion.ToString;
end;
Text := nStrs.DelimitedText;
end; _GetXNode(nXN, 'VerInfo_IncludeVerInfo', nStr).Text := True.ToString(TUseBoolStrs.True);
end
else
begin
{删除其他版本信息}
nXN.Delete('VerInfo_MajorVer');
nXN.Delete('VerInfo_MinorVer');
nXN.Delete('VerInfo_Release');
nXN.Delete('VerInfo_Build');
nXN.Delete('VerInfo_Keys');
end;
end;
if nBackup then
begin
nPath := ExtractFilePath(nFiles[nFileIndex]) + '\dproj_bak\';
ForceDirectories(nPath);
nStr := nPath + ExtractFileName(nFiles[nFileIndex]) + '.#' + nOldVersion.ToString + '#.bak';
if FileExists(nStr) then
TFile.Delete(nStr);
TFile.Copy(nFiles[nFileIndex], nStr);
end;
nXDOC.SaveToFile(nFiles[nFileIndex], TTextEncoding.teUTF8, True, False, True);
except
on E: Exception do
Writeln('错误: ' + E.Message);
end;
end;
finally
nStrs.Free;
nXDOC.Free;
end;
Writeln('');
Writeln('******** 处理完毕 ********')
except
on E: EAbort do;
on E: Exception do
begin
Writeln('错误: ', E.Message);
nAutoClose := False;
end;
end;
if not nAutoClose then
begin
Writeln('');
Writeln('按任意键关闭');
Read(nStr);
end;
end.

Delphi工程版本号修改工具的更多相关文章

  1. Git学习(一) 版本号管理工具

    Git 是一个分布式版本号控制工具.它的作者 Linus Torvalds 是这样给我们介绍 Git  -- The stupid content tracker(傻瓜式的内容跟踪器) 1. Git ...

  2. git版本号管理工具的上手

    git是一个分布式的版本号管理工具 和其它集中式版本号管理 工具相比具有下面长处: 1.能够在不联网的情况下开发 2.能够方便的建立本地分支 3.本地化的日志,高速获得信息 git命令的使用 mkdi ...

  3. [c#][福利]BTTool种子文件修改工具

    前言 不知道各位看官是否有过类似的经历.好不容易找到一个电影的种子文件,想用百度云的离线下载功能去下载文件,却被百度云无情提示“离线文件因含有违规内容被系统屏蔽无法下载”!假设有这么一个场景,比如最近 ...

  4. 用户组修改工具samusrgrp

    用户组修改工具samusrgrp   Windows系统内置了很多用户组,如Administrators.PowerUser.User等.用户隶属不同的组,就具备对应的权限.Kali Linux提供一 ...

  5. 网络数据修改工具netsed

    网络数据修改工具netsed   通过修改网络数据,可以绕过软件和防火墙的限制,达到特定的目的.Kali Linux提供一个简易数据修改工具netsed.该工具支持对TCP和UDP的数据进行修改.渗透 ...

  6. (外挂破解)Cheat Engine(内存修改工具)V6.2中文版软件介绍

    Heat Engine是一款内存修改编辑工具,Cheat Engine允许你修改你的游戏,所以你将总是赢.它包括16进制编辑,反汇编程序,内存查找工具.与同类修改工具相比,它具有强大的反汇编功能,且自 ...

  7. Android 获取手机的厂商、型号、Android系统版本号等工具类(转载)

    Android 获取手机的厂商.型号.Android系统版本号等工具类 1.获取手机制造厂商 2.获取手机型号 3.获取手机系统当前使用的语言 4.获取Android系统版本号 5.获取手机IMEI串 ...

  8. jar包名修改工具

    jar包名修改工具 软件传送门:链接: https://pan.baidu.com/s/12StRdEkYGmMn1DuNSquXSw   提取码: i9w1 闲暇之余,利用jarjar.jar写了一 ...

  9. Delphi开发的IP地址修改工具

    用Delphi进行开发的,直接修改注册表,需重启电脑后才生效

随机推荐

  1. Thirft框架快速入门

    Thrift介绍1.什么是thrift?thrift早期由facebook内部团队开发,主要用于实现跨语言间的方法调用,属于远程方法调用的一种,后开源纳入apache中,成为了apache thrif ...

  2. 手把手教你用npm发布一个包,详细教程

    我们已经实现了路由的自动化构建,但是我们可以看到,一大串代码怼在里面.当然你也可以说,把它封装在一个JS文件里面,然后使用require('./autoRoute.js')给引入进来,那也行.但是,为 ...

  3. python识别验证码——一般的数字加字母验证码识别

    1.验证码的识别是有针对性的,不同的系统.应用的验证码区别有大有小,只要处理好图片,利用好pytesseract,一般的验证码都可以识别 2.我在识别验证码的路上走了很多弯路,重点应该放在怎么把图片处 ...

  4. webpack2使用ch8-loader解析less less自动添加浏览器前缀

    1 目录结构  安装依赖 "less": "^2.7.2","less-loader": "^4.0.3", 2 web ...

  5. DSCP 与IP 优先级IP优先级

    在IPv4的报文头中,TOS字段是1字节,如下图所示.根据RFC1122的定义,IP优先级(IPPrecedence)使用最高3比特(第0-2比特).+++++++++++++++++++++++++ ...

  6. 扩展js,实现c#中的string.format方便拼接字符串

    //"{0}-{1}-{2}".format("xx","yy","zz") //显示xx-yy-zz String.p ...

  7. maven的介绍

    刚来通信行业的国企上班,面试的时候很尴尬的问道"maven是干什么的?"""maven是项目管理工具吗?是怎么管理的?(理解类似于协同等办公OA一样的软件了)& ...

  8. 【转】循环冗余校验(CRC)算法入门引导

    原文地址:循环冗余校验(CRC)算法入门引导 参考地址:https://en.wikipedia.org/wiki/Computation_of_cyclic_redundancy_checks#Re ...

  9. 浅试 Webview 一app 加载 H5小游戏

    整体架构: InventionActivity:实现UI的实例化,基本的按钮Activity之间跳转 GameActivity:实现UI的实例化,Webview的基本使用 MyProgressDial ...

  10. bootstrap 鼠标悬停显示

    1. <button type="button" rel="drevil" data-content="报名截止时间:'+time+'" ...