Установка CultureInfo до компиляции и всегда сбрасывается после - PullRequest
2 голосов
/ 13 марта 2012

Я пытаюсь выполнить задачу, которая изменяет локаль / культуру, используемую во время компиляции для проекта конвейера содержимого 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 всегда выполняет (не в моем случае), а другие говорят, что нет способа гарантировать, что цель всегда запускается после сборки.Я не нашел точной информации об этом в Google.

Я знаю, что есть возможность использовать PostBuildEvent и настроить его на постоянный запуск, но для запуска команды будет использоваться Exec, и яподозреваю, что он будет работать в отдельном потоке, нанося поражение своей цели (я установил CurrentThread.CultureInfo для изменения локали).

Итак, есть ли способ гарантировать, что цель всегда запускается?В качестве альтернативы, есть ли другой способ сказать VS2010 запускать компиляцию с определенной культурой?

Ссылки на документацию, явно разъясняющие проблему, были бы очень признательны.

- Окончательное решение, следуя ответу Севы -

Конвейер содержимого 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, в результате чего одно из определений переопределит другое.

1 Ответ

0 голосов
/ 13 марта 2012

Вы можете использовать PostBuildEvent, потому что вы можете настроить его выполнение всегда после сборки. Однако, как вы правильно заметили, использование задачи Exec здесь не сработает. Однако PostBuildEvent фактически расширяется с помощью свойства $ (PostBuildEventDependsOn). Вам нужно будет определить это свойство:

<PropertyGroup>
  <PostBuildEventDependsOn>RestoreOriginalLocale</PostBuildEventDependsOn>
</PropertyGroup>

Цель RestoreOriginalLocale - это то, что вы имели в своей цели AfterBuild:

<Target Name="RestoreOriginalLocale">
  <SetLocale Locale="@(OrigLocale)" /> 
</Target>

Ваша цель BeforeBuild все еще нужна, она остается такой же, как вы написали в своем вопросе.

Чтобы убедиться, что PostBuildEvent выполняется при сбое (и, следовательно, требует выполнения RestoreOriginalLocale), необходимо установить для свойства RunPostBuildEvent значение Always. Вы можете сделать это через IDE или вручную отредактировав свой файл .csproj.

...