Подтвердить что ты не робот

Локализовать AssemblyInfo.cs

My AssemblyInfo содержит информацию о моем продукте, компании и т.д. Эти данные в настоящее время жестко закодированы в файле cs:

[assembly: AssemblyCompany("My Company.")]
[assembly: AssemblyProduct("MyProduct")]
[assembly: AssemblyCopyright("Copyright © 2012 My Company, Inc. All Rights Reserved.")]
[assembly: AssemblyTrademark("MyProduct is a trademark of MyCompany Software.")]
[assembly: AssemblyCulture("")]

Я хочу локализовать эти тексты, но я не могу сделать следующее:

[assembly: AssemblyCompany(Resources.MyConpany)]

Есть ли способ обойти это?

4b9b3361

Ответ 1

Да, это возможно. Сами атрибуты очень редко читаются людьми, которые заботятся о языке. Однако они также используются компилятором С# для создания версии компиляции /win 32res по умолчанию.

Что влияет на то, что вы видите, когда смотрите на свойства сборки в проводнике, используя элемент контекстного меню "Свойства" и посмотрите вкладку "Сведения". На экране Windows отображаются не атрибуты сборки, они ничего не знают о управляемых сборках. То, что вы видите, это данные в неуправляемом ресурсе, встроенные в сборку.

Вы можете видеть, как выглядят эти неуправляемые ресурсы с помощью Visual Studio. Используйте File + Open + File и перейдите к образцу EXE-сборки. Вы получите древовидную структуру встроенных ресурсов, типичная .NET-программа должна иметь как минимум три из них. Значок, манифест, который делает программу совместимой с UAC. И ресурс версии, тот, который вам интересен. Откройте это node, и вы увидите ресурс с идентификатором 1, отмеченный [Нейтральный]. Нейтральная версия ресурса "работает на любом языке". Дважды щелкните его, чтобы открыть редактор (не будет работать в Express), вы можете увидеть, как атрибуты сборки сопоставляются с свойствами ресурса ресурса.

Что вам нужно сделать, это создать собственную версию этих неуправляемых ресурсов - версию, использующую более одного языка. Это требует записи файла .rc, ресурса script, который затем скомпилируется в файл .res инструментом rc.exe, неуправляемым компилятором ресурсов. Затем вы можете использовать Project + Properties, Application, "Resource File", чтобы сообщить компилятору об этом.

Остерегайтесь, что это немного больно и подвержено ошибкам, rc.exe - это темпераментный инструмент, и вы теряете прямую связь между AssemblyInfo.cs и тем, что видите в Windows, это элемент обслуживания. Лучший способ сделать это - использовать фиктивный проект на С++ и использовать его встроенный редактор ресурсов, чтобы собрать его.

Ответ 2

Даже если невозможно "прямо" локализовать вашу AssemblyInfo (например, использовать Resources.MyCompany, как показано в вашем вопросе), то, что вы могли бы сделать, это сгенерировать полную AssemblyInfo во время компиляции до фактического компиляции.

Вот несколько примеров, как сделать это со свободным и открытым исходным кодом Задачи сообщества MSBuild:

Обе ссылки показывают, как сделать это в отдельном файле MSBuild, который вызывается для сборки решения, но также можно поместить его непосредственно в файл .csproj, что означает, что создание AssemblyInfo.cs даже работает при построении решение в Visual Studio.

Вот пример из одного из моих проектов, как это сделать.
(обратите внимание, что в этом примере я не генерирую целый AssemblyInfo.cs, а отдельный файл, содержащий только номер версии!)

Вызов Службы сообщества MSBuild находится в . csproj file:

  <Target Name="BeforeBuild">
    <PropertyGroup>
      <ProdVer>0.0</ProdVer>
    </PropertyGroup>
    <PropertyGroup>
      <ProdVer Condition="'$(VersionNumber)' != ''">$(VersionNumber)</ProdVer>
    </PropertyGroup>
    <AssemblyInfo CodeLanguage="CS" OutputFile="AssemblyVersion.cs" AssemblyVersion="$(ProdVer)" AssemblyFileVersion="$(ProdVer)" />
  </Target>

Строка <AssemblyInfo ... вызывает задачи сообщества MSBuild для создания файла AssemblyVersion.cs, номер версии которого установлен на $(ProdVer).
$(ProdVer) устанавливается на 0.0 несколько строк раньше, а когда есть переменная среды с именем $(VersionNumber), которая не пуста, значение $(ProdVer) установлено на это значение.
И $(VersionNumber) устанавливается перед вызовом моей сборки script, просто вызывая set VersionNumber=1.1 в пакетном файле.

Это означает, что при создании из 0.0 с номером версии 0.0 и с номером реальной версии (в моем примере 1.1) при построении через build script.

Конечно, получение вашей локализованной информации о компании в сборку таким образом - это больше работы, чем просто вызов Resources.MyCompany где-то, но можно локализовать AssemblyInfo по вашему желанию.