在启动画面上编写汇编版本
Writing assembly version on splash screen
我按照 Kent Boogaart 的 excellent article 了解如何将动态内容添加到初始屏幕。从我现在可以在初始屏幕上看到版本号的意义上讲,一切正常。然而,问题是文章使用 $(Version)
属性,在我的例子中是 1.0.0.0
。
我正在使用 shared AssemblyInfo.vb 并且需要从此文件中获取下一个 major/minor/build/revision 数字以将它们绘制在初始屏幕上。共享的 AssemblyInfo 文件包含类似 2.5.*
的版本号。我需要 MSBuild (2.5.abc.xyz
) 生成的实际数字。
我考虑过在 UsingTask
中使用反射从程序集中获取版本号,但由于此任务是 运行 在 构建过程之前,该程序集还没有将在以下构建中生成的版本号。此外,那时程序集可能根本不存在(例如 Clean 在构建之前的命令)。
我安装了 MSBuild Community Tasks,但除了 SvnVersion
任务外什么都看不到。
有人可以帮我把要生成的版本号发到我的 UsingTask
吗?
终于!对于其他尝试执行相同操作的人,这里是步骤,假设您使用的是驻留在解决方案目录中的共享 AssemblyInfo(它也适用于默认的 AssemblyInfo,但您需要相应地调整路径和文件名):
- 在您的计算机上下载并安装 MSBuild Community Tasks。
- 将目标文件(一个简单的 XML 扩展名为
.targets
的文件)添加到您的项目。
- 添加
UsingTask
Kent Boogaart 的文章,我在问题中将其链接到此文件。这将在初始图像上执行实际版本写入。
- 使用
<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\("\d+\.\d+((\.\*)|(\.\d+\.\d+))?"\)"
ReplacementText="Assembly: AssemblyVersion("$(Major).$(Minor).$(Build).$(Revision)")" />
<FileUpdate Files="$(SolutionDir)SharedAssemblyInfo.vb"
Regex="Assembly: AssemblyFileVersion\("\d+\.\d+((\.\*)|(\.\d+\.\d+))?"\)"
ReplacementText="Assembly: AssemblyFileVersion("$(Major).$(Minor).$(Build).$(Revision)")" />
<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 修订号。您可能需要根据自己的需要进行调整。
我按照 Kent Boogaart 的 excellent article 了解如何将动态内容添加到初始屏幕。从我现在可以在初始屏幕上看到版本号的意义上讲,一切正常。然而,问题是文章使用 $(Version)
属性,在我的例子中是 1.0.0.0
。
我正在使用 shared AssemblyInfo.vb 并且需要从此文件中获取下一个 major/minor/build/revision 数字以将它们绘制在初始屏幕上。共享的 AssemblyInfo 文件包含类似 2.5.*
的版本号。我需要 MSBuild (2.5.abc.xyz
) 生成的实际数字。
我考虑过在 UsingTask
中使用反射从程序集中获取版本号,但由于此任务是 运行 在 构建过程之前,该程序集还没有将在以下构建中生成的版本号。此外,那时程序集可能根本不存在(例如 Clean 在构建之前的命令)。
我安装了 MSBuild Community Tasks,但除了 SvnVersion
任务外什么都看不到。
有人可以帮我把要生成的版本号发到我的 UsingTask
吗?
终于!对于其他尝试执行相同操作的人,这里是步骤,假设您使用的是驻留在解决方案目录中的共享 AssemblyInfo(它也适用于默认的 AssemblyInfo,但您需要相应地调整路径和文件名):
- 在您的计算机上下载并安装 MSBuild Community Tasks。
- 将目标文件(一个简单的 XML 扩展名为
.targets
的文件)添加到您的项目。 - 添加
UsingTask
Kent Boogaart 的文章,我在问题中将其链接到此文件。这将在初始图像上执行实际版本写入。 - 使用
<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\("\d+\.\d+((\.\*)|(\.\d+\.\d+))?"\)"
ReplacementText="Assembly: AssemblyVersion("$(Major).$(Minor).$(Build).$(Revision)")" />
<FileUpdate Files="$(SolutionDir)SharedAssemblyInfo.vb"
Regex="Assembly: AssemblyFileVersion\("\d+\.\d+((\.\*)|(\.\d+\.\d+))?"\)"
ReplacementText="Assembly: AssemblyFileVersion("$(Major).$(Minor).$(Build).$(Revision)")" />
<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 修订号。您可能需要根据自己的需要进行调整。