Встраивание локализованных спутниковых DLL в приложение EXE - PullRequest
0 голосов
/ 01 июля 2019

У меня есть проект C ++ CLR / CLI, мне интересно, как встроить локализованный сателлитный dll в мое exe-приложение, я нашел похожие решения, но он для проектов C #, который довольно сильно отличается от структуры моего проекта. Можно ли встраивать его прямо в двоичный файл? Кстати, у меня возникают проблемы с пространствами имен, кажется, что мое пользовательское пространство имен не связано с моим локализованным файлом ресурсов.

Ответы [ 2 ]

0 голосов
/ 01 июля 2019

Используйте бесплатный упаковщик приложений для объединения файлов в один исполняемый файл.

https://enigmaprotector.com/en/aboutvb.html

Этот бесплатный, я им пользуюсь, и он очень хорошо работает для меня.

0 голосов
/ 01 июля 2019

Я часами искал решение для проекта C ++ CLR / CLI, который сильно отличается от проектов C #, которые, по-видимому, поставляются с Build Action и Custom Tool Namespace всеми этими опциями, которых у нас нет в Проект CLR / CLI, это действительно важно, особенно если мы изменили пространства имен, поэтому вместо него мы должны использовать Resource Logical Name. Вот мой ответ как решить проблемы пространства имен, это также работает для локализованных файлов ресурсов, связанных со спутниковыми библиотеками.

После того, как ваша локализованная спутниковая DLL будет сгенерирована, включите ее в свой проект как Compiled Managed Resource, чтобы установить ее, открыв свойство файла и установив Item Type. В таких проектах, как C #, вы не найдете этого, но что-то похожее на «Встроенный ресурс» В любом случае это предназначено только для проектов C ++ CLR / CLI. Если вы изменили пространства имен, не забудьте установить Resource Logical Name соответствующего файла ресурсов.

Следующим шагом является создание некоторого кода для встраивания этого dll в наше exe-приложение, вот хороший вариант для этого:

Поскольку C ++ CLR / CLI не поддерживает лямбда-выражения, мы должны сделать это следующим образом:

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();
            }

Так что теперь больше не нужны спутниковые библиотеки для загрузки ваших локализованных ресурсов.

...