【问题标题】:Merge ResX file at runtime?在运行时合并 ResX 文件?
【发布时间】:2015-05-18 00:39:15
【问题描述】:

我正在从代码中生成/构建一个自定义的 .Net 托管资源文件(一个 .resx 文件)

C#VB.Net 中,我如何设计一种能够将我的自定义 .resx 文件合并、加入或嵌入到 .net 程序集中的方法(更多或不像VS编译器默认的那样)?

所以,一方面我有一个Application.exe(已经编译),另一方面我有一个resources.resx,我的意图是“将 resx 合并到已编译的程序集中。

任何类型的信息都将不胜感激,因为我没有找到任何关于它的信息。

PS:唯一的必要条件是不要使用 3rd 方工具,例如 ILMerge

【问题讨论】:

  • 你不能使用 DLL 来获取资源吗?它没有编译到 EXE 中,但允许独立于 EXE 的更新
  • @Plutonix 你是什么意思?我没理解对,如果你问我是否可以在resx表中添加一个dll?那么是的,如果您问我是否可以使用 dll 代替 .resx?:那么不,因为我不会放弃我编写 +1.000 行代码以各种方式管理 .ResX 文件所花费的所有工作(一个辅助类来添加/读取/删除资源等)。感谢您的评论
  • 如果可以帮助您了解解决此问题的方法,这里是来源:pastebin.com/qYccnJVh
  • 所以你已经有了一个有或没有一些资源的 EXE。在某些时候,您想使用 resx 作为新项目的存储库向其中添加更多资源项目?大概这发生在已部署的应用程序上?
  • 与其将 .resx 嵌入到 exe 中,不如在运行时加载 .resx 文件,使用类似 ResourceManager.CreateFileBasedResourceManager msdn.microsoft.com/en-us/library/…

标签: c# vb.net winforms visual-studio resx


【解决方案1】:

我终于通过一种不同的方法解决了,在我创建了 ResX 文件之后,我所做的是在运行时编译一个 .net 程序集并将该 ResX 文件分配为要编译的程序集的嵌入资源,因此,结果是一个已编译的 .net dll,可以合并或任何我想要的,我可以随时从该 dll 中提取 ResX 文件,很好!

如果有人知道比这更简单/更容易的选择,请随时发布答案(寻求帮助或仅用于剩余的赏金)

示例代码如下:

Imports System.CodeDom.Compiler
Imports System.IO
Imports System.Reflection

Public Class Form1

Private Sub Test() Handles MyBase.Shown

    ' Create the ResX file.
    Dim resX As New ResXManager(Path.Combine(Application.StartupPath, "C:\MyResources.resx"))
    With resX
        .Create(replace:=True)
        .AddResource(Of String)("String Resource", "Hello World!", "String Comment")
    End With

    ' Compile an assembly.dll that contains the ResX file as an embedded resource.
    Dim codeProvider As CodeDomProvider = CodeDomProvider.CreateProvider("VB") ' or New VBCodeProvider()
    Dim parameters As CompilerParameters = New CompilerParameters()
    With parameters
        .GenerateExecutable = False
        .OutputAssembly = "C:\Assembly.dll"
        .EmbeddedResources.Add("C:\MyResources.resx")
    End With
    Dim results As CompilerResults = codeProvider.CompileAssemblyFromSource(parameters, "Public class ResourceClass : End Class")

    ' Read the assembly.
    Dim assembly As Assembly = assembly.LoadFile("c:\Assembly.dll")

    ' Extract/read the ResX file from assembly.
    Dim embeddedFileName As String = "MyResources.resx"
    Dim targetFilePath As String = "C:\NewMyResources.resx"
    Using s As Stream = assembly.GetManifestResourceStream(embeddedFileName)
        Dim buffer As Byte() = New Byte(CInt(s.Length - 1)) {}
        Dim read As Integer = s.Read(buffer, 0, CInt(s.Length))
        Using fs As New FileStream(targetFilePath, FileMode.Create)
            fs.Write(buffer, 0, buffer.Length)
        End Using
    End Using

End Sub

End Class

我从这里得到了一些帮助:

Generating DLL assembly dynamically at run time

Read embedded file from assembly

【讨论】:

    【解决方案2】:

    如果没有外部工具(手动或现有工具),您将无法将资源合并到已编译的文件中。这可能是你没有找到任何相关信息的原因。手动合并文件是possible,但我推荐另一种方法。

    如果可能,您可以在编译发生之前尝试generating your resource file,例如在 Visual Studio 中使用text template。然后在编译时将通常的行为应用于生成的 resx 文件,该文件将在程序集中被提升。

    如果无法在编译前生成资源文件,则必须使用外部工具

    【讨论】:

    • 感谢您的回答,您谈论的是外部工具,但我已经尝试过 IlMerge、ILMergeGUI、.Net Shrink 和 SmartAssembly,但它们都无法合并 resx(他们无法识别那种 . resx 文件,并且将扩展名更改为 .dll 将不起作用),那么您说合并是不可能的,嗯,加入或嵌入会发生什么?
    • 合并意味着两个已编译的元素(例如:code.dll 和 resources.dll)。如果您查看我的答案中的链接,您应该会看到可能对您有所帮助的加入/嵌入示例
    • 谢谢,但我没有通过您提供的链接找到如何操作
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-12
    • 1970-01-01
    相关资源
    最近更新 更多