自动增加 Android App 的版本号

一般的 C# 应用程序中都有一个 AssemblyInfo.cs 文件,其中的 AssemblyVersion attribute 就可以用来设置该应用程序的版本号。譬如,

[assembly: AssemblyVersion("1.0.*")]

  

这样设置的 AssemblyVersion attribute,其版本号中的构建编号(Build Number),在每次编译(Build)该应用程序时,就会自动加1。这样,版本号中的主、次版本号由手动设置,而构建编号由编译程序(MSBuild)自动管理,省去了很多麻烦。

但 Android App 的版本号却无法使用这种方式,因为 Android App 的版本号存在于 AndroidManifest.xml 中:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
		  android:versionCode="3" android:versionName="1.0"
		  package="mypackage"
		  android:installLocation="auto">
	<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
	<application android:label="MyPackage.Android"
				 android:theme="@style/MainTheme"
				 android:allowBackup="false">
	</application>
</manifest>

  

在这个 AndroidManifest.xml 文件中,App 的版本号(versionName)是“1.0”,构建编号(versionCode)是“3”。我们希望能够像 C# 程序一样,由编译程序自动管理构建编号。但似乎还没有这样实现自动管理的编译程序,所以只能自己动手实现类似的功能。

网上找到了一段C#代码,可以完成自动增加 versionCode 的功能:

////////////////////////////////////////////////////////
// AutoVersion
//      Increment the Android VersionCode automatically
// Version
//      1.0
// Author
//      prowyh@hotmail.com
// Date
//      2022-11-22
// Curtesy
//      9to5answer.com/auto-increment-version-code-in-android-app
////////////////////////////////////////////////////////

using System.Text.RegularExpressions;

namespace AutoVersion
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string file = "AndroidManifest.xml";
            if (args.Length > 0) { file = args[0]; }

            try
            {
                string text = File.ReadAllText(file);
                Regex regx = new(@"(?<A>android:versionCode="")(?<VER>\d+)(?<B>"")", RegexOptions.IgnoreCase);
                Match match = regx.Match(text);
                int verCode = int.Parse(match.Groups["VER"].Value) + 1;
                string ntext = regx.Replace(text, "${A}" + verCode + "${B}", 1);

                File.WriteAllText(file, ntext);
            }
            catch (Exception exp)
            {
                using StreamWriter sw = new("AutoVersion.log");
                sw.Write(exp.Message);
            }
        }
    }
}

  

将此代码编译为 AutoVersion.exe,将其包括在 Visual Studio 的 pre-build 事件所执行的命令行中(如下图),即可。

 

这样,每次点击 “Build Solution” 进行编译时,都会先执行 AutoVersion.exe,完成对 AndroidManifest.xml 中 versionCode 的自动增1 操作。

下面是 AutoVersion.cs 的 PowerShell 版本:

<#
 .SYNOPSIS
    AutoVersion.ps1
 .DESCRIPTION
    PowerShell script for automatically incrementing the Android VersionCode.
 .VERSION
    1.0
 .AUTHOR
    prowyh@hotmail.com
 .DATE
    2022-11-22
#>
$content = Get-Content AndroidManifest.xml
[regex]$rx = "(?<A>android:versionCode="")(?<VER>\d+)(?<B>"")"
$m = $rx.Matches($content)
$nv = $([System.Int32]$m[0].Groups["VER"].Value + 1)
$nvCode = $m[0].Groups["A"].Value, $nv, $m[0].Groups["B"].Value -join ""
$content -replace "android:versionCode=""(\d+)""", $nvCode | Out-File -FilePath AndroidManifest.xml

  

2022-11-24 更新

对于 .NET MAUI 项目,Android.Manifest.xml 与 Xamarin.Forms 的一样,但位置变了。可以通过 mauiApp.csproj 项目文件进行设置,如下所示:

<Project Sdk="Microsoft.NET.Sdk">
......

	<Target Name="PreBuild" BeforeTargets="PreBuildEvent" Condition="$([MSBuild]::GetTargetPlatformIdentifier('$(TargetFramework)')) == 'android'">
	  <Exec Command="D:\AutoVersion\AutoVersion.exe $(ProjectDir)\Platforms\Android\AndroidManifest.xml" />
	</Target>

</Project>

  

需要注意的是,因为一个MAUI解决方案中包含了若干项目,在编译(Build)时,每个项目都要 Build 一遍,导致 AutoVersion 执行多次。解决的办法是使用条件(Condition) attribute 将 AutoVersion 的执行限制在编译 Android 项目时。

 

posted @ 2022-11-22 15:49  野峰-WildPeak  阅读(390)  评论(2编辑  收藏  举报