在 iOS、Android 和 OS X 上获取 Xamarin 程序集构建日期 [英] Get a Xamarin assembly build date on iOS, Android and OS X

查看:20
本文介绍了在 iOS、Android 和 OS X 上获取 Xamarin 程序集构建日期的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的代码中,我需要一个 Xamarin 程序集构建日期.在 Windows 上,我可以使用 链接器时间戳.但是在 iOS 上这不起作用.我想它也不适用于 OS X,因为 Portable Executable 标头特定于 Windows.

In my code I need a Xamarin assembly build date. On Windows I can use linker time stamp. However on iOS this does not work. I guess it would not work on OS X too as Portable Executable header is specific to Windows.

还有一个选项可以嵌入带有日期的资源,但是我想避免在这个特定项目中使用资源.

There is also an option to embed a resource with a date, however I would like to avoid using resources in this particular project.

有什么方法可以找到适用于 iOS、Android 和 OS X 的 Xamarin 程序集构建日期?

Are there any way to find a Xamarin assembly build date that works on iOS, Android and OS X?

推荐答案

一种方法是使用 MSBuild 任务将构建时间替换为应用程序属性返回的字符串.我们在具有 Xamarin.Forms、Xamarin.Android 和 Xamarin.iOS 项目的应用中成功地使用了这种方法.

One approach would be to use an MSBuild task to substitute the build time into a string that is returned by a property on the app. We are using this approach successfully in an app that has Xamarin.Forms, Xamarin.Android, and Xamarin.iOS projects.

如果使用 msbuild,这可以是一个 MSBuild 内联任务,而在使用 xbuild 的 Mac 上,它需要是一个为 Mono 编译的 MSBuild 自定义任务.

If using msbuild, this can be an MSBuild inline task, while on Mac using xbuild, it will need to be an MSBuild custom task compiled for Mono.

通过将所有逻辑移到构建任务中来简化,并使用 Regex 而不是简单的字符串替换,以便每次构建都可以修改文件而无需重置".

Simplified by moving all of the logic into the build task, and using Regex instead of simple string replace so that the file can be modified by each build without a "reset".

MSBuild 内联任务定义(保存在本示例的 Xamarin.Forms 项目本地的 SetBuildDate.targets 文件中):

The MSBuild inline task definition (saved in a SetBuildDate.targets file local to the Xamarin.Forms project for this example):

<Project xmlns='http://schemas.microsoft.com/developer/msbuild/2003' ToolsVersion="12.0">

  <UsingTask TaskName="SetBuildDate" TaskFactory="CodeTaskFactory" 
    AssemblyFile="$(MSBuildToolsPath)Microsoft.Build.Tasks.v12.0.dll">
    <ParameterGroup>
      <FilePath ParameterType="System.String" Required="true" />
    </ParameterGroup>
    <Task>
      <Code Type="Fragment" Language="cs"><![CDATA[

        DateTime now = DateTime.UtcNow;
        string buildDate = now.ToString("F");
        string replacement = string.Format("BuildDate => "{0}"", buildDate);
        string pattern = @"BuildDate => ""([^""]*)""";
        string content = File.ReadAllText(FilePath);
        System.Text.RegularExpressions.Regex rgx = new System.Text.RegularExpressions.Regex(pattern);
        content = rgx.Replace(content, replacement);
        File.WriteAllText(FilePath, content);
        File.SetLastWriteTimeUtc(FilePath, now);

   ]]></Code>
    </Task>
  </UsingTask>

</Project>

添加了一个 MSBuild Exec 步骤以删除只读属性.必须喜欢 TFS.

Added an MSBuild Exec step to remove readonly attribute. Gotta love TFS.

在目标 BeforeBuild 中的 Xamarin.Forms csproj 文件中调用 MSBuild 任务(内联或编译,内联方法为 xbuild 注释):

Invoking the MSBuild task (inline or compiled, inline approach is commented for xbuild) in the Xamarin.Forms csproj file in target BeforeBuild:

  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
       Other similar extension points exist, see Microsoft.Common.targets.  -->
  <!--<Import Project="SetBuildDate.targets" />-->
  <UsingTask AssemblyFile="$(MSBuildProjectDirectory)BI.Framework.BuildExtensions.dll" TaskName="Some.Framework.BuildExtensions.BuildDateTask" />
  <Target Name="BeforeBuild">
    <Exec Command="attrib $(MSBuildProjectDirectory)BuildMetadata.cs -r" />
    <!--<SetBuildDate FilePath="$(MSBuildProjectDirectory)BuildMetadata.cs" />-->
    <BuildDateTask FilePath="$(MSBuildProjectDirectory)BuildMetadata.cs" />
  </Target>

FilePath 属性设置为 Xamarin.Forms 项目中的 BuildMetadata.cs 文件,该文件包含一个带有字符串属性 BuildDate,构建时间将被替换为:

The FilePath property is set to a BuildMetadata.cs file in the Xamarin.Forms project that contains a simple class with a string property BuildDate, into which the build time will be substituted:

public class BuildMetadata
{
    public static string BuildDate => "This can be any arbitrary string";
}

将此文件 BuildMetadata.cs 添加到项目中.每次构建都会修改它,但以允许重复构建(重复替换)的方式进行修改,因此您可以根据需要在源代码管理中包含或省略它.

Add this file BuildMetadata.cs to project. It will be modified by every build, but in a manner that allows repeated builds (repeated replacements), so you may include or omit it in source control as desired.

添加:

这是一个自定义 MSBuild 任务,用于在 Mac 上使用 xbuild 进行构建时替换 MSBuild 内联任务:

Here is a custom MSBuild task to replace the MSBuild inline task for when building with xbuild on Mac:

using System;
using System.IO;
using System.Text.RegularExpressions;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;

namespace Some.Framework.BuildExtensions
{
    public class BuildDateTask : Task
    {
        #region Methods

        /// <summary>
        /// Called automatically when the task is run.
        /// </summary>
        /// <returns><c>true</c>for task success, <c>false</c> otherwise.</returns>
        public override bool Execute()
        {
            const string pattern = @"BuildDate => ""([^""]*)""";
            var now = DateTime.UtcNow;
            var buildDate = now.ToString("F");
            var replacement = $"BuildDate => "{buildDate}"";
            var content = File.ReadAllText(FilePath);
            var rgx = new Regex(pattern);
            content = rgx.Replace(content, replacement);
            File.WriteAllText(FilePath, content);
            File.SetLastWriteTimeUtc(FilePath, now);
            return true;
        }

        #endregion Methods

        #region Properties

        [Required]
        public string FilePath { get; set; }

        #endregion Properties
    }
}

通过 xbuild 为 Release 构建此自定义任务,然后将输出的自定义任务 dll 复制到要为其设置构建日期的项目的项目目录中.

Build this custom task for Release via xbuild, then copy the output custom task dll to the project directory of the project for which you want to set the build date.

这篇关于在 iOS、Android 和 OS X 上获取 Xamarin 程序集构建日期的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆