gpt4 book ai didi

silverlight - 嵌入字体强制 Silverlight 项目始终重建

转载 作者:行者123 更新时间:2023-12-02 00:38:01 25 4
gpt4 key购买 nike

我的 Silverlight 4 项目遇到了一个奇怪的问题,尽管这是我以前见过的问题。基本上,嵌入字体会强制我的 Silverlight 应用程序始终重建,即使一切都是最新的。这种情况很糟糕,因为字体嵌入任务会占用大量内存并最终导致 VS 崩溃。我希望能够从命令行构建项目,但无论我的本地项目是什么都已过时,因此“运行”命令会强制进行另一次重建。我试图从我的 msbuild 日志中删除一些相关的日志信息。

Project "D:\Projects\Test\Test.Web\Test.Web.csproj" (10) is building "D:\Projects\Test\Test.SL\Test.SL.csproj" (2:4) on node 1 (default targets).
Building with tools version "4.0".
// Build operation starts normally (well, the dependency set on the server project is forcing the SL application to build).
...
Target "ResolveReferences" skipped. Previously built successfully.
// A bunch of tasks are skipped (like this one)
...
Target "SubsetFontsSilverlight" in file "C:\Program Files\MSBuild\Microsoft\Expression\Blend\Silverlight\v4.0\SubsetFontSilverlight.targets" from project "D:\Projects\Test\Test.SL\Test.SL.csproj" (target "PrepareResources" depends on it):
Using "SubsetFontsSilverlight" task from assembly "C:\Program Files\MSBuild\Microsoft\Expression\Blend\Silverlight\v4.0\SubsetFontTask.dll".
Task "SubsetFontsSilverlight"
Done executing task "SubsetFontsSilverlight".
Done building target "SubsetFontsSilverlight" in project "Test.SL.csproj".
// this task never gets skipped
...
Target "MainResourcesGeneration" in file "C:\Program Files\MSBuild\Microsoft\Silverlight\v4.0\Microsoft.Silverlight.Common.targets" from project "D:\Projects\Test\Test.SL\Test.SL.csproj" (target "PrepareResources" depends on it):
Building target "MainResourcesGeneration" completely.
Input file "obj\Debug\Fonts\Fonts.zip" is newer than output file "obj\Debug\Test.SL.g.resources".
// note that the Fonts.zip file now makes the resources file out of date
...
Target "CoreCompile" in file "C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\Microsoft.CSharp.Targets" from project "D:\Projects\Test\Test.SL\Test.SL.csproj" (target "Compile" depends on it):
Building target "CoreCompile" completely.
Input file "obj\Debug\Test.SL.g.resources" is newer than output file "obj\Debug\Test.SL.pdb".
// and the full recompile begins...

无论如何,如果字体文件没有改变,有没有办法停止运行字体任务?因为不断重建真的很烦人。

更新:项目文件中的示例字体。

<BlendEmbeddedFont Include="Fonts\MyriadPro-BoldIt.otf">
<IsSystemFont>True</IsSystemFont>
<All>True</All>
<AutoFill>True</AutoFill>
<Characters>
</Characters>
<Uppercase>True</Uppercase>
<Lowercase>True</Lowercase>
<Numbers>True</Numbers>
<Punctuation>True</Punctuation>
</BlendEmbeddedFont>

更新 2:

我想发布一个小的重现项目,但我不确定将 zip 文件扔到哪里。无论如何,一个人可以在几秒钟内被掀起。以下是步骤:

  1. 创建 Sillverlight 应用程序(Blend 或 VS,尽管无论如何您都需要 Blend 才能工作)

  2. 在 Blend 中使用字体管理器(工具 -> 字体管理器),您可能必须打开 MainPage.xaml 才能启用它。嵌入“Tahoma”字体。

现在,每次点击“重建”时,您都可以验证 csc.exe 是否每次都在运行,无论是否有任何更改。

最佳答案

我通过修改我的 SubsetFontSilverlight.target 文件解决了这个问题。这不是一个完整的解决方案,不一定对每个人都有效,但对我有用。

目标文件可以在 C:\Program Files\MSBuild\Microsoft\Expression\Blend\Silverlight\v4.0 中找到,至少在我的机器上是这样。

此处的主要思想是使用 MSBUILD 目标输入/输出属性来查看是否需要更新中间 Font.zip 文件。我只是对输出文件路径进行了硬编码,因为我总是使用默认的 Blend 字体位置 - 但可以从单独的字体文件中构建它。

我设置的条件是,如果 Font.zip 文件比嵌入字体文件和项目文件更新,则应跳过该任务。这样,如果您添加/减去一种字体或替换其中一种字体,字体将被重新嵌入,但如果没有更改(或只是代码更改),font.zip 将保持不变。

如果未嵌入字体,手动将 fonts.zip 添加到资源集合中很重要 - 如果代码需要重新编译但字体可能会被保留,msbuild 会记得将字体文件包含到资源中.这就是为什么我在主嵌入任务之后添加了一个新任务来运行。

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<UsingTask AssemblyFile="SubsetFontTask.dll" TaskName="Microsoft.Expression.SubsetFontTask.SubsetFontsSilverlight" />
<UsingTask AssemblyFile="SubsetFontTask.dll" TaskName="Microsoft.Expression.SubsetFontTask.CleanSubsetFonts" />

<ItemGroup Condition="'$(BuildingInsideVisualStudio)'=='true'">
<AvailableItemName Include="BlendEmbeddedFont"/>
</ItemGroup>

<ItemGroup>
<!-- Files that we specify as target inputs for msbuild target timestamp check -->
<FontEmbedRelatedFile Include="$(MSBuildProjectFile)" />
<FontEmbedRelatedFile Include="@(BlendEmbeddedFont)" />

<!-- Anticipated font file locations -->
<FontOutputFile Include="$(IntermediateOutputPath)\Fonts\Fonts.zip" />
</ItemGroup>

<!--
this task runs after the main subset task - basically it checks if the task got skipped, and if so
it adds the projected font output files to the resources collection
-->
<Target Name='AfterFontEmbed' AfterTargets="SubsetFontsSilverlight"
Condition="'@(BlendEmbeddedFont)' != '' AND '@(BlendSubsettedFont)' == ''">
<Message Text="Adding font files to the resource collection because Font embed was skipped" Importance="normal" />
<ItemGroup>
<Resource Include="@(FontOutputFile)" />
</ItemGroup>
</Target>

<Target Name='SubsetFontsSilverlight'
Inputs="@(FontEmbedRelatedFile)" Outputs="@(FontOutputFile)"
DependsOnTargets="$(SubsetFontsDependsOn)"
Condition="'@(BlendEmbeddedFont)' != ''">
<Message Text="Embedding font subsets" Importance="normal" />
<SubsetFontsSilverlight
Fonts="@(BlendEmbeddedFont)" XamlFiles="@(Page)" Resources="@(Resources)"
IntermediateFilesDirectory="$(IntermediateOutputPath)"
>
<Output TaskParameter="SubsettedFonts" ItemName="Resource"/>
<!-- save our list of embedded font files for later use -->
<Output TaskParameter="SubsettedFonts" ItemName="BlendSubsettedFont"/>
</SubsetFontsSilverlight>
</Target>

<Target Name='CleanSubsetFonts' DependsOnTargets="$(CleanSubsetFontsDependsOn)" Condition="'@(BlendEmbeddedFont)' != ''">
<CleanSubsetFonts
Fonts="@(BlendEmbeddedFont)"
IntermediateFilesDirectory="$(IntermediateOutputPath)"
/>
</Target>

<PropertyGroup>
<PrepareResourcesDependsOn>
SubsetFontsSilverlight;
$(PrepareResourcesDependsOn);
</PrepareResourcesDependsOn>
</PropertyGroup>

<PropertyGroup>
<CleanDependsOn>
$(CleanDependsOn);
CleanSubsetFonts;
</CleanDependsOn>
</PropertyGroup>

</Project>

Visual Studio 仍然不能很好地注意到项目是最新的,但是当它构建它们时,核心编译任务不会每次都运行,并且 dll 文件不会被不必要地覆盖。这意味着您可以在命令行上运行编译器,在调试时将 VS 设置为“从不构建”,并且仍然加载正确的调试符号。

我在我能想到的大多数情况下(清理之前/之后、丢失文件、仅代码更改、项目更改等)测试了它,它似乎运行良好——这意味着字体在那里,一切都没有总是被重新编译。

关于silverlight - 嵌入字体强制 Silverlight 项目始终重建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3765391/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com