Сборка ресурсов сборки с помощью AssemblyBuilder - PullRequest
15 голосов
/ 26 декабря 2011

Сценарий: я хочу создать сателлитные сборки, которые являются сборками ресурсов.Эта сборка содержит только скомпилированные ресурсы (ResourceWriter). Цель состоит в том, чтобы создать сборки ресурсов вне VS и добавить их в приложение, и это в моем приложении C #

Atm Я использую AssemblyBuilder для создания сборки.Работает, но нет информации о сохраненной сборке.Нет Cultureinfo, ключ или что-то еще.Сборка не выполняется приложением с исключением «Отсутствует ресурс Manfifest».: (

Если возможно, я хочу остаться с AssemblyBuilder или с использованием CodeDomProvider.

Вопрос : Что необходимо, чтобы иметь возможность добавить новую сборку спутника в мое приложение?достаточно иметь папку с культурой (en-US) и сборку с ресурсами en-US?

Question2 : можно ли предоставить некоторую метаинформацию, такую ​​как Version, Культура к сборке?

Вопрос3 : Достаточно ли добавить ресурсы в сборку?

Код:

AssemblyBuilder builder = AppDomain.CurrentDomain.DefineDynamicAssembly(
                        assemblyName, AssemblyBuilderAccess.RunAndSave, resourceFolder);

builder.AddResourceFile(name, assemblyFileName);
builder.Save(assemblyName.Name);

Для любоговид помощи, я был бы благодарен. Заранее спасибо

Ответы [ 2 ]

7 голосов
/ 27 декабря 2011

Нашел решение.

Источник: http://www.dotnet247.com/247reference/msgs/58/290731.aspx

Объяснение: Первое Похоже, AssemblyBuilder только связывает ресурс со сборкой , но не встроен.Во-вторых, ресурс должен быть в модуле , чтобы его увидела основная сборка.(Я не люблю встраивать ресурс в модуль, но, похоже, нет способа встроить уже существующий ресурс)

Код:

        string myAsmName = "WriteSatelliteAssembly.resources";
        string myAsmFileName = myAsmName + ".dll";
        string resourceName = "WriteSatelliteAssembly.MyResource2.fr.resources";
        string path;

        path = AppDomain.CurrentDomain.BaseDirectory + "fr-FR";
        AppDomain appDomain = Thread.GetDomain();
        AssemblyName asmName = new AssemblyName();
        asmName.Name = myAsmName;
        asmName.CodeBase = path;
        asmName.CultureInfo = new CultureInfo("fr");

        AssemblyBuilder myAsmBuilder = appDomain.DefineDynamicAssembly(
            asmName,
            AssemblyBuilderAccess.RunAndSave, path);

        **ModuleBuilder** myModuleBuilder =
            myAsmBuilder.DefineDynamicModule(myAsmFileName,
            myAsmFileName);
        **IResourceWriter** rw =
            myModuleBuilder.DefineResource(resourceName,
            "My Description",ResourceAttributes.Public);

        rw.AddResource("resName","My (dynamic) resource value.");
        rw.AddResource("resName2","My (dynamic) second resource value.");

        myAsmBuilder.Save(myAsmFileName);

Сокращение доказательства:

Связанный ресурс в сборке

.file nometadata 'TestProjectResourceManager.Properties.Resources.en-US.resources'
    .hash = (57 DD 82 37 9E B3 BA 8A 27 D0 69 90 37 67 22 23   // W..7....'.i.7g"#
             A0 1C F7 47 )                                     // ...G
.mresource public TestProjectResourceManager.Properties.Resources
{
  .file 'TestProjectResourceManager.Properties.Resources.en-US.resources' at 0x00000000
}

встроенный ресурс в сборке

.mresource public 'TestProjectResourceManager.Properties.Resources.en-US.resources'
{
  // Offset: 0x00000000 Length: 0x000000EE
}
.module TestProjectResourceManager_2.resources.dll

Веселитесь

2 голосов
/ 26 декабря 2011

Для создания сборок понадобятся следующие инструменты.

  1. resgen.exe
  2. al.exe
  3. ildasm.exe

al.exe - это программа, которая встраивает ресурсы в спутниковую сборку.Но al.exe будет принимать ресурсы только в двоичном формате .resources.Но наши входные данные, как правило, представляют собой либо простые текстовые файлы ресурсов, либо файлы ресурсов на основе XML в формате .resx.Resgen.exe используется для преобразования этих альтернативных форм ресурсов в двоичный формат .resources, приемлемый для al.exe.

ildasm.exe: Если вы помните, что делает Visual Studio IDE, вы увидите, что естьперевод имени между структурой каталогов вашего файла ресурсов и тем, как этот файл ресурсов известен внутри сборки.Поскольку мы используем IDE Visual Studio для генерации ресурсов по умолчанию и процесс расширения для генерации сателлитных сборок, оба механизма должны создавать сборки с одинаковой иерархией именования для файлов ресурсов.

Поэтому мы используем ildasmисследовать библиотеки DLL, которые генерирует Visual Studio IDE, чтобы выяснить, какова структура, и использовать тот же механизм для генерации сателлитных сборок.Вы также можете исследовать спутниковые сборки, используя ildasm, чтобы убедиться, что вы правильно поняли имена.Это будет полезно для отладки ошибок менеджера ресурсов, сообщающего вам, что он не может найти ресурс.

Теперь, когда обрисованы в общих чертах инструменты, как нам преобразовать файл внешнего ресурса в вспомогательную сборку?Как отмечено ниже, это три (на самом деле, два) шага процесса.

Шаг 0: Установите пути для resgen и al.exe:

@set path=%path%;
    "C:\Program Files\Microsoft Visual Studio .NET\FrameworkSDK\Bin";
     c:\winnt\microsoft.NET\framework\v1.0.3705

Шаг 1: Используйте resgen длясоздайте файл .resources из файла .resx.

Resgen MyText.resx

Приведенная выше команда создаст файл с именем:

MyText.resources

Шаг 2: Используйте al.exe для создания вспомогательной сборки:

Al.exe
     /t:lib
     /embed:MyText.en-gb.Resources,MyApplication.MyText.en-gb.Resources
     /culture:hi-gb
     /out:MyApplication.resources.dll

Здесь стоит отметить пару вещей:

/t:lib: Says you are interested in a .dll.

/embed:MyText.en-gb.Resources,MyApplication.MyText.en-gb.Resources : Embeds and renames the resource to a target name to match the Visual Studio IDE naming structure.

/culture:hi-gb : Identifies the culture in which you are interested.

/out:MyApplication.resources.dll : Name of the DLL in which you are interested.

Сгенерированный .dll должен иметь соглашение об именах, чтобы .NET мог его найти.Также обратите внимание, что вам нужно указать настройку культуры, хотя культура доступна в названии файлов ресурсов.Таким образом, это должно быть упомянуто в обоих местах.

Поместите сателлитную сборку в соответствующий каталог. После создания сателлитной сборки физически скопируйте DLL в следующий каталог:

\MyApplication\bin\en-gb\MyApplication.Resources.DLL

В случае нескольких файлов ресурсов:

\MyApplication\resources\files\CommonResources.resx
\MyApplication\resources\files\Module1Resources.resx
\MyApplication\resources\files\Module2Resources.resx

И вы можете определить ключи для этих ресурсов в отдельной иерархии следующим образом:

\MyApplication\resources\keys\CommonKeys.cs
\MyApplication\resources\keysModule1Keys.cs
\MyApplication\resources\keys\Module2Keys.cs

Для сценария пакетной программы:пожалуйста, обратитесь к моему блогу http://samithenerd.blogspot.com/2011/12/batch-program-for-creating-satellite.html

...