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

查看:63
本文介绍了在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内联任务,而在Mac上使用xbuild时,它将需要是为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>

在Xamarin.Forms项目中,FilePath属性设置为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构建此发布的自定义任务,然后将输出的自定义任务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天全站免登陆