使用AssemblyBuilder构建资源程序集

本文关键字:程序集 资源 构建 AssemblyBuilder 使用 | 更新日期: 2023-09-27 18:18:59

场景:我想创建卫星程序集,它们是资源程序集。此程序集仅包含已编译的资源(ResourceWriter)。目标是在VS之外创建资源集并将它们添加到应用程序中,这在我的c#应用程序

我正在使用AssemblyBuilder创建程序集。它可以工作,但没有存储有关程序集的信息。没有文化信息、密钥或其他任何东西。程序集不会被应用程序以Missing manifest Resource异常获取。(

如果可能的话,我想留在AssemblyBuilder或使用CodeDomProvider。

问题:什么是必要的,能够添加新的卫星组装到我的应用程序?有一个包含区域性(en-US)的文件夹和一个包含en-US资源的程序集是否足够?

Question2:是否有可能向程序集提供版本、文化等元信息?

Question3:列表是否足以将资源添加到程序集?

代码:

AssemblyBuilder builder = AppDomain.CurrentDomain.DefineDynamicAssembly(
                        assemblyName, AssemblyBuilderAccess.RunAndSave, resourceFolder);
builder.AddResourceFile(name, assemblyFileName);
builder.Save(assemblyName.Name);
对于任何形式的帮助,我都将感激不尽。提前感谢

使用AssemblyBuilder构建资源程序集

找到解决方案。

来源:http://www.dotnet247.com/247reference/msgs/58/290731.aspx

解释:首先,似乎AssemblyBuilder只将资源链接到程序集,而不是嵌入。其次,资源必须在Module中,才能被主程序集看到。(我不喜欢在模块内创建资源,但似乎没有办法嵌入已经存在的资源)

代码:

        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

您将需要以下工具来创建程序集。

  1. exe
  2. al.exe
  3. ildasm.exe
exe是将资源嵌入到附属程序集中的程序。但是。exe只接受。resources二进制格式的资源。但是我们的输入通常是纯文本资源文件或.resx格式的基于xml的资源文件。Resgen.exe用于将这些替代形式的资源转换为。resources二进制格式。

ildasm.exe:如果您还记得Visual Studio IDE正在做什么,您将看到在您的资源文件目录结构和该资源文件在程序集中的已知方式之间存在名称转换。因为我们使用Visual Studio IDE来生成默认资源,使用外部进程来生成附属程序集,所以这两种机制必须为资源文件生成具有相同命名层次结构的程序集。

因此,我们使用ildasm来检查Visual Studio IDE生成的dll,以找出结构是什么,并使用相同的机制来生成附属程序集。您还可以使用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从。resx文件创建。resources文件。

Resgen MyText.resx
上面的命令将创建一个名为 的文件
MyText.resources

步骤2:使用。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