我已经看过使用Xcode甚至Xamarin Studio执行此操作的解决方案,但与Visual Studio没有任何关系。
理想情况下,我希望项目的每个版本都能自动增加Info.plist文件中的CFBundleVersion
值。
<key>CFBundleVersion</key>
<string>9</string>
我甚至不知道从哪里开始,并且无法在包含Visual Studio的任何内容上找到文章/博客文章/教程。
这可能吗?
只想添加我在Windows 8.1上使用Visual Studio 2015。
答案 0 :(得分:0)
与你在同一条船上,就像没有找到合适的解决方案一样,我决定创造自己的。也许迟到总比没有好! :)
在我的情况下,我使用了非常有用的自动版本设置工具(在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 for CI和构建自动化。因此,该程序成为远程构建代理的功能,然后我可以将其添加为Bamboo构建计划中的任务。