我正在尝试执行一项任务,该任务更改 XNA 内容管道项目在编译时使用的语言环境/文化,并在编译结束后恢复原始文件。目的是允许在非英语机器中正确解析浮点数。
到目前为止,我正在使用 BeforeBuild 和 AfterBuild,如下所示:
<UsingTask TaskName="PressPlay.FFWD.BuildTasks.SetLocale" AssemblyFile="PressPlay.FFWD.BuildTasks.dll" />
<Target Name="BeforeBuild">
<SetLocale> <!-- By default, set to 'en-US' -->
<Output TaskParameter="PrevLocale" ItemName="OrigLocale" />
</SetLocale>
</Target>
<Target Name="AfterBuild">
<SetLocale Locale="@(OrigLocale)" />
</Target>
它可以正常工作,除非在编译期间发生错误(无效的 XML 或 ContentSerializer 错误),之后不会重置语言环境。SO中的答案是矛盾的,因为有人说AfterBuild总是执行(不是我的情况),而其他人说没有办法确保目标总是在构建后运行。我还没有在谷歌周围找到关于这个的确切信息。
我知道可以选择使用PostBuildEvent
并将其设置为始终运行,但它会用于Exec
运行命令,我怀疑它会在单独的线程中运行,从而违背了它的目的(我设置CurrentThread.CultureInfo
为更改语言环境)。
那么,有没有办法确保目标始终运行?或者,有没有其他方法可以告诉 VS2010 运行具有特定文化的编译?
非常感谢明确澄清该问题的文档链接。
--最终解决方案,按照 Seva 的回答 --
XNA 的内容管道不声明PreBuildEvent
也不PostBuildEvent
. 其他必需的属性(RunPostBuildEvent
和PreBuildEventDependsOn
)PostBuildEventDependsOn
也没有定义。但是,如果您定义它们,内容管道将像在任何其他项目中一样充分利用它们。
因此,我必须对 contentcsproj 文件进行的更改是:
<!-- Added to ensure the locale is always restored -->
<PropertyGroup>
<RunPostBuildEvent>Always</RunPostBuildEvent>
</PropertyGroup>
<!-- Reference includes, project references and other stuff -->
<!-- ... -->
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA Game Studio\$(XnaFrameworkVersion)\Microsoft.Xna.GameStudio.ContentPipeline.targets" />
<!-- Customizations to change locale before compilation and restore it after -->
<!-- Needed to properly treat dots in the XMLs as decimal separators -->
<UsingTask TaskName="PressPlay.FFWD.BuildTasks.SetLocale" AssemblyFile="PressPlay.FFWD.BuildTasks.dll" />
<!-- Apparently ContentPipeline.targets does not define PreBuildEvent and PostBuildEvent -->
<!-- However, they are still used if defined -->
<Target Name="PreBuildEvent" DependsOnTargets="$(PreBuildEventDependsOn)"/>
<Target Name="PostBuildEvent" DependsOnTargets="$(PostBuildEventDependsOn)"/>
<PropertyGroup>
<PreBuildEventDependsOn>
$(PreBuildEventDependsOn);
EstablishUSLocale
</PreBuildEventDependsOn>
</PropertyGroup>
<PropertyGroup>
<PostBuildEventDependsOn>
$(PostBuildEventDependsOn);
RestoreOriginalLocale
</PostBuildEventDependsOn>
</PropertyGroup>
<Target Name="EstablishUSLocale">
<SetLocale Locale="en-US">
<Output TaskParameter="PrevLocale" ItemName="OrigLocale" />
</SetLocale>
</Target>
<Target Name="RestoreOriginalLocale">
<SetLocale Locale="@(OrigLocale)" />
</Target>
使用此解决方案可以间接解决另一个问题,即如果另一个项目重新定义 BeforeBuild 或 AfterBuild 时可能出现的潜在问题,从而导致其中一个定义覆盖另一个定义。