首页 > 解决方案 > 将本地化的卫星 dll 嵌入到 exe 应用程序中

问题描述

我有一个 C++ CLR/CLI 项目,我想知道如何将本地化的卫星 dll 嵌入到我的 exe 应用程序中,我找到了类似的解决方案,但它适用于与我的项目结构完全不同的 C# 项目。是否可以将其直接嵌入到二进制文件中?顺便说一句,我遇到了命名空间的问题,似乎我的自定义命名空间没有链接到我的本地化资源文件。

标签: c++.netwinformsc++-cliclr

解决方案


我一直在寻找几个小时来寻找 C++ CLR/CLI 项目的解决方案,这与显然附带的 C# 项目Build Action以及Custom Tool Namespace我们在 CLR/CLI 项目中没有的所有这些选项相比有很大不同,这真的很重要,特别是如果我们改变了命名空间,所以我们必须使用它Resource Logical Name。这是如何解决命名空间问题的答案,这也适用于链接到卫星 dll 的本地化资源文件。

生成本地化卫星 dll 后,将其包含在项目中,因为Compiled Managed Resource您可以通过打开其文件属性并设置Item Type. 在诸如 C# 之类的项目中,您不会发现它,而是类似“嵌入式资源”之类的东西。无论如何,这仅适用于 C++ CLR/CLI 项目。如果您更改了命名空间,请不要忘记设置Resource Logical Name相应的资源文件。

下一步是编写一些代码,以便将该 dll 嵌入到我们的 exe 应用程序中,这是一个很好的方法:

由于 C++ CLR/CLI 不支持 lambda 表达式,我们必须这样做:

private: System::Reflection::Assembly^  currentDomainAssemblyResolve(System::Object^  sender, System::ResolveEventArgs^  args) {

        System::Reflection::AssemblyName^  assemblyName = gcnew System::Reflection::AssemblyName(args->Name);

        System::String^  resourceName = assemblyName->Name + ".dll";

        System::IO::Stream^  stream = System::Reflection::Assembly::GetExecutingAssembly()->GetManifestResourceStream(resourceName);

        array<Byte>^  assemblyData = gcnew array<Byte>((unsigned long) stream->Length);
        try {
            stream->Read(assemblyData, 0, assemblyData->Length);
        } finally {
            if (stream != nullptr) delete stream;
        }

        return System::Reflection::Assembly::Load(assemblyData);
    }

用法:

//Put it in your constructor before InitializeComponent()
    MyClass(void) {
                AppDomain::CurrentDomain->AssemblyResolve += gcnew System::ResolveEventHandler(this, &MyNameSpace::MyClass::currentDomainAssemblyResolve);
                InitializeComponent();
            }

因此,现在不再需要卫星 dll 来加载您的本地化资源。


推荐阅读