【问题标题】:Can I auto-increment the CFBundleVersion value in the Info.plist file using Visual Studio?我可以使用 Visual Studio 自动增加 Info.plist 文件中的 CFBundleVersion 值吗?
【发布时间】:2015-11-05 07:53:00
【问题描述】:

我已经看到了使用 Xcode 甚至 Xamarin Studio 执行此操作的解决方案,但没有使用 Visual Studio。

理想情况下,我希望项目的每个构建都自动增加 Info.plist 文件中的 CFBundleVersion 值。

<key>CFBundleVersion</key>
<string>9</string>

我什至不知道从哪里开始,也找不到任何包含 Visual Studio 的文章/博客文章/教程。

这可能吗?

只是想补充一点,我在 Windows 8.1 上使用 Visual Studio 2015。

【问题讨论】:

  • 查看以下 SO 帖子:[此处][1] [此处][2] [1]:stackoverflow.com/questions/826777/… [2]:stackoverflow.com/questions/356543/…
  • 哦,可能与 iOS 无关 - 你的 VS 配置和设置是什么?
  • @rholmes 是的,看到这些帖子,但不幸的是,它们并不直接兼容。抱歉,我忘了包括设置——编辑了我的帖子。 VS 2015 和 Windows 8.1。谢谢!

标签: ios visual-studio xamarin


【解决方案1】:

与您在同一条船上,因为找不到合适的解决方案,所以我决定创建自己的解决方案。也许迟到总比没有好! :)

在我的例子中,我使用了非常有用的自动版本设置工具(在 NuGet 上可用)来自动更新我的程序集信息,但希望它也能更新 Info.plist 信息,因为这是 HockeyApp 用来跟踪和通知新版本的.

最后,我拼凑了一个最小的 C# 程序,它读取 AssemblyInfo.cs,从那里获取版本信息并编辑 Info.plist XML 文件并将其写回。

如果我没有进行大量的偏执检查,这将是一个 20 行的程序,以免冒着不可挽回地破坏 Info.plist 的风险(即使这样,它也会创建该文件的备份)。

“魔法”归结为两种方法,第一种是我在 SO 上找到的:

阅读 AssemblyInfo.cs:

private static string GetVersionFromAssemblyInfo(string infile)
{
    var version = String.Empty;

    var readText = File.ReadAllLines(infile);
    var versionInfoLines = readText.Where(t => t.Contains("[assembly: AssemblyVersion"));
    foreach (var item in versionInfoLines)
    {
        version = item.Substring(item.IndexOf('(') + 2, item.LastIndexOf(')') - item.IndexOf('(') - 3);
    }
    return version;
}

编辑 Info.plist,其中程序集信息元组的前 3 个元素变为 CFBundleShortVersionString,最后一个元素变为 CFBundleVersion,HockeyApp 将其用作内部版本号。

LINQ 的不稳定是由于 Apple 在该文件中呈现键/值对的方式有点怪异:

 private static bool SetVersionInInfoPlist(string infoplistFile, string version, string number)
    {
        var xelements = XDocument.Load(infoplistFile);
        var dict = from el in xelements.Root?.Elements() select el;
        // ReSharper disable once ConditionIsAlwaysTrueOrFalse
        if (dict == null) return false;

        var cfshortversion =
            from el in dict.Descendants("key")
            where el.Value == "CFBundleShortVersionString"
            select el.ElementsAfterSelf().FirstOrDefault();
        ;
        // ReSharper disable once ConditionIsAlwaysTrueOrFalse
        if (cfshortversion == null) return false;
        cfshortversion.FirstOrDefault()?.SetValue(version);

        var cfversion =
            from el in dict.Descendants("key")
            where el.Value == "CFBundleVersion"
            select el.ElementsAfterSelf().FirstOrDefault();

        // ReSharper disable once ConditionIsAlwaysTrueOrFalse
        if (cfversion == null) return false;
        cfversion.FirstOrDefault()?.SetValue(number);

        // Make backup
        try
        {
            File.Copy(infoplistFile, $"{infoplistFile}-backup", true);
        }
        catch (Exception)
        {
            Console.WriteLine($"Failed to create backup of {infoplistFile}. Will not edit.");
            return false;
        }

        try
        {
            using (StringWriter sw = new StringWriter())
            {
                using (XmlWriter xWrite = XmlWriter.Create(sw))
                {
                    xelements.Save(xWrite);
                }
            }
            xelements.Save(infoplistFile);
        }
        catch (Exception)
        {
            Console.WriteLine($"Failed to save the edited {infoplistFile}.");
            return false;
        }

        Console.WriteLine($"Successfully edited and saved new {infoplistFile}.");
        return true;

    }

编辑:我还应该补充一点,我使用 Bamboo 进行 CI 和构建自动化。因此,该程序成为远程构建代理的一项功能,然后我可以将其作为任务添加到 Bamboo 构建计划中。

【讨论】:

    猜你喜欢
    • 2020-05-03
    • 1970-01-01
    • 2013-07-25
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-28
    • 2019-06-05
    相关资源
    最近更新 更多