【问题标题】:Writing assembly version on splash screen在启动画面上编写程序集版本
【发布时间】:2018-04-15 01:20:46
【问题描述】:

我关注了 Kent Boogaart 的 excellent article,了解如何向初始屏幕添加动态内容。从某种意义上说,我现在可以在启动屏幕上看到版本号。然而问题是文章使用了$(Version) 属性,在我的例子中是1.0.0.0

我正在使用shared AssemblyInfo.vb,并且需要从此文件中获取下一个主要/次要/内部版本/修订号,以便在启动屏幕上绘制它们。共享的 AssemblyInfo 文件包含一个版本号,例如 2.5.*。我需要将由 MSBuild (2.5.abc.xyz) 生成的实际数字。

我曾考虑在 UsingTask 中使用反射从程序集中获取版本号,但由于此任务在构建过程之前运行,因此程序集还没有版本号将在以下构建中生成。此外,此时该程序集可能根本不存在(例如,构建前的 Clean 命令)。

我安装了 MSBuild 社区任务,但除了 SvnVersion 任务之外什么都看不到。

有人可以帮我将要生成的版本号发送到我的UsingTask吗?

【问题讨论】:

  • 添加VB工程默认的SplashScreen。它包含您的应用程序的修订号。
  • @kiLLua:这不是 WinForms 项目。 WPF SplashScreen 模板只是一个没有文本的 PNG 文件。
  • 执行程序集应该如何知道 next 构建程序集的版本?为什么不显示当前运行的应用程序的版本?
  • @mm8:请参阅我上面链接的文章。在 WPF 中使用内置的SplashScreen 构建操作时在初始屏幕上显示动态内容并不是那么直接,因为 WPF 只接受 位图文件 用于此目的。为了解决这个限制,我们在构建时使用 MSBuild 任务在位图上动态写入版本号。
  • 如果您在 build 时编写版本,有什么问题?只显示写好的版本号?

标签: wpf vb.net msbuild splash-screen


【解决方案1】:

终于!对于其他尝试这样做的人,这里是步骤,假设您使用的是位于解决方案目录中的共享 AssemblyInfo(它也可以用于默认 AssemblyInfo,但您需要相应地调整路径和文件名):

  1. 在您的机器上下载并安装MSBuild Community Tasks
  2. 将目标文件(扩展名为 .targets 的简单 XML 文件)添加到您的项目中。
  3. 添加在 Kent Boogaart 的文章中提出的 UsingTask 我在问题中链接到此文件。这将对启动图像执行实际版本写入。
  4. 使用<Version><FileUpdate><AddTextToImage> 任务(前两个在MSBuild 中可用,第三个来自我们在步骤3 中添加的UsingTask)将新版本号写入共享的AssemblyInfo 文件并启动图片。

最终的.targets 文件如下所示:

<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <UsingTask TaskName="AddTextToImage" TaskFactory="CodeTaskFactory" AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
    <ParameterGroup>
      <InputPath ParameterType="System.String" Required="true" />
      <OutputPath ParameterType="System.String" Required="true" />
      <TopMiddlePoint ParameterType="System.String" Required="true" />
      <Text1 ParameterType="System.String" Required="true" />
      <Text2 ParameterType="System.String" Required="false" />
      <Text3 ParameterType="System.String" Required="false" />
    </ParameterGroup>
    <Task>
      <Reference Include="WindowsBase" />
      <Reference Include="PresentationCore" />
      <Reference Include="PresentationFramework" />
      <Reference Include="System.Xaml" />
      <Using Namespace="System" />
      <Using Namespace="System.Globalization" />
      <Using Namespace="System.IO" />
      <Using Namespace="System.Windows" />
      <Using Namespace="System.Windows.Media" />
      <Using Namespace="System.Windows.Media.Imaging" />
      <Code Type="Fragment" Language="cs">
        <![CDATA[         
              var originalImageSource = BitmapFrame.Create(new Uri(InputPath));

              var visual = new DrawingVisual();

              using (var drawingContext = visual.RenderOpen())
              {
                drawingContext.DrawImage(originalImageSource, new Rect(0, 0, originalImageSource.PixelWidth, originalImageSource.PixelHeight));

                var typeFace = new Typeface(new FontFamily("Arial"), FontStyles.Normal, FontWeights.Bold, FontStretches.Normal);
                var formattedText = new FormattedText(Text1, System.Globalization.CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeFace, 18, Brushes.Red);
                var topMiddlePoint = Point.Parse(TopMiddlePoint);
                var point = new Point(topMiddlePoint.X - (formattedText.Width / 2), topMiddlePoint.Y);
                drawingContext.DrawText(formattedText, point);

                if(!string.IsNullOrEmpty(Text2))
                {
                  formattedText = new FormattedText(Text2, System.Globalization.CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeFace, 18, Brushes.Red);
                  topMiddlePoint.Y += formattedText.Height + 5;
                  point = new Point(topMiddlePoint.X - (formattedText.Width / 2), topMiddlePoint.Y);
                  drawingContext.DrawText(formattedText, point);
                }

                if(!string.IsNullOrEmpty(Text3))
                {
                  formattedText = new FormattedText(Text3, System.Globalization.CultureInfo.InvariantCulture, FlowDirection.LeftToRight, typeFace, 18, Brushes.Red);
                  topMiddlePoint.Y += formattedText.Height + 5;
                  point = new Point(topMiddlePoint.X - (formattedText.Width / 2), topMiddlePoint.Y);
                  drawingContext.DrawText(formattedText, point);
                }

                drawingContext.Close();
              }

              var renderTargetBitmap = new RenderTargetBitmap(originalImageSource.PixelWidth, originalImageSource.PixelHeight, originalImageSource.DpiX, originalImageSource.DpiY, PixelFormats.Pbgra32);

              renderTargetBitmap.Render(visual);

              var bitmapFrame = BitmapFrame.Create(renderTargetBitmap);

              BitmapEncoder encoder = new PngBitmapEncoder();

              encoder.Frames.Add(bitmapFrame);

              using (var stream = File.OpenWrite(OutputPath))
              {
                encoder.Save(stream);
                stream.Close();
              }
            ]]>
      </Code>
    </Task>
  </UsingTask>

  <PropertyGroup>
    <MajorVersion>2</MajorVersion>
    <MinorVersion>5</MinorVersion>
  </PropertyGroup>

  <Target Name="BeforeBuild">
    <Version BuildType="Automatic" RevisionType="Automatic" Major="$(MajorVersion)" Minor="$(MinorVersion)">
      <Output TaskParameter="Major" PropertyName="Major" />
      <Output TaskParameter="Minor" PropertyName="Minor" />
      <Output TaskParameter="Build" PropertyName="Build" />
      <Output TaskParameter="Revision" PropertyName="Revision" />
    </Version>

    <FileUpdate Files="$(SolutionDir)SharedAssemblyInfo.vb"
            Regex="Assembly: AssemblyVersion\(&quot;\d+\.\d+((\.\*)|(\.\d+\.\d+))?&quot;\)"
            ReplacementText="Assembly: AssemblyVersion(&quot;$(Major).$(Minor).$(Build).$(Revision)&quot;)" />

    <FileUpdate Files="$(SolutionDir)SharedAssemblyInfo.vb"
            Regex="Assembly: AssemblyFileVersion\(&quot;\d+\.\d+((\.\*)|(\.\d+\.\d+))?&quot;\)"
            ReplacementText="Assembly: AssemblyFileVersion(&quot;$(Major).$(Minor).$(Build).$(Revision)&quot;)" />

    <SvnVersion LocalPath=".">
      <Output TaskParameter="Revision" PropertyName="SvnRevision" />
    </SvnVersion>

    <AddTextToImage InputPath="$(ProjectDir)Resources\Splash.png"
                    OutputPath="$(ProjectDir)Resources\SplashWithVersion.png"
                    TopMiddlePoint="250,150"
                    Text1="$(Major).$(Minor).$(Build).$(Revision)"
                    Text2="SVN Version: $(SvnRevision)" />

    <Message Text="Updated version number on splash screen to: $(Major).$(Minor).$(Build).$(Revision)" Importance="high"/>
  </Target>
</Project>

这将更新您的 AssemblyInfo 和输出图像。请注意,您必须在 Visual Studio 中将输出图像标记为 SplashScreen(作为生成操作)。另请注意,我正在启动屏幕上同时编写程序集版本和 SVN 修订号。您可能需要根据自己的需要进行调整。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-05-29
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 2018-03-19
    • 1970-01-01
    • 2014-05-28
    • 1970-01-01
    相关资源
    最近更新 更多