2016-06-24 2 views
1

У меня есть простое консольное приложение C++/CLI, которое запускает другой процесс и читает его STDOUT и STDERR. Он использует внешние (сторонние) библиотеки. Я пытаюсь внедрить их в .exe-образ, чтобы сделать автономный исполняемый файл для развертывания.Ошибка приложения C++/CLI после IlMerge

выход ILMerge:

 
ilmerge /log /out:test1.exe test.exe 
ILMerge version 2.12.803.0 
Copyright (C) Microsoft Corporation 2004-2006. All rights reserved. 
ILMerge /log /out:test1.exe test.exe 
Set platform to 'v2', using directory 'C:\Windows\Microsoft.NET\Framework64\v2.0.50727\..\v2.0.50727' for mscorlib.dll 
Running on Microsoft (R) .NET Framework v2.0.50727 
mscorlib.dll version = 2.0.0.0 
The list of input assemblies is: 
     test.exe 
Trying to read assembly from the file 'test.exe'. 
     Successfully read in assembly. 
     There were no errors reported in test's metadata. 
Checking to see that all of the input assemblies have a compatible PeKind. 
     test.PeKind = ILonly, Requires32bits 
All input assemblies have a compatible PeKind value. 
Using assembly 'test' for assembly-level attributes for the target assembly. 
Merging assembly 'test' into target assembly. 
Copying 4 Win32 Resources from assembly 'test' into target assembly. 
Transferring entry point '.mainCRTStartupStrArray(System.String[])' from assembly 'test' to assembly 'test1'. 
     There were no errors reported in the target assembly's metadata. 
ILMerge: Writing target assembly 'test1.exe'. 
AssemblyResolver: Assembly 'test' is referencing assembly 'Microsoft.VisualC'. 
     AssemblyResolver: Attempting referencing assembly's directory. 
     AssemblyResolver: Did not find the assembly in referencing assembly's directory. 
     AssemblyResolver: Attempting input directory. 
     AssemblyResolver: Did not find the assembly in the input directory. 
     AssemblyResolver: Attempting user-supplied directories. 
     AssemblyResolver: No user-supplied directories. 
     AssemblyResolver: Attempting framework directory. 
Can not find PDB file. Debug info will not be available for assembly 'Microsoft.VisualC'. 
Resolved assembly reference 'Microsoft.VisualC' to 'C:\Windows\Microsoft.NET\Framework64\v2.0.50727\..\v2.0.50727\Microsoft.VisualC.dll'. (Used framework directory.) 
Location for referenced module 'KERNEL32.dll' is '' 
Location for referenced module 'MSVCR100.dll' is '' 
Location for referenced assembly 'mscorlib' is 'C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorlib.dll' 
     There were no errors reported in mscorlib's metadata. 
Location for referenced assembly 'System' is 'C:\Windows\Microsoft.NET\Framework64\v2.0.50727\system.dll' 
     There were no errors reported in System's metadata. 
Location for referenced assembly 'Microsoft.VisualC' is 'C:\Windows\Microsoft.NET\Framework64\v2.0.50727\Microsoft.VisualC.dll' 
     There were no errors reported in Microsoft.VisualC's metadata. 
ILMerge: Done. 

Одно было немного путаешь меня - использование Framework64 библиотек рассматривающих x86 платформу исходного приложения.

Запуск test1.exe приводит к следующему вывод в консоли:

 
Unhandled Exception: System.TypeInitializationException: The type initializer for '' threw an exception. ---> .ModuleLoadException: The C++ module failed to load during registration 
for the unload events. 
---> System.TypeInitializationException: The type initializer for ".ModuleUninitializer" threw an exception. ---> System.MissingMethodException: Method not found: "Void System.Threading.Monitor.Enter(System.Object, Boolean ByRef)". 
    in System.Runtime.CompilerServices.RuntimeHelpers.PrepareDelegate(Delegate d) 
    in System.AppDomain.add_DomainUnload(EventHandler value) 
    in .ModuleUninitializer..ctor() in f:\dd\vctools\crt_bld\self_x86\crt\src\minternal.h:line 255 
    in .ModuleUninitializer..cctor() in f:\dd\vctools\crt_bld\self_x86\crt\src\minternal.h:line 217 
    --- End of inner exception stack trace --- 
    in .RegisterModuleUninitializer(EventHandler handler) in f:\dd\vctools\crt_bld\self_x86\crt\src\minternal.h:line 292 
    in .LanguageSupport.InitializeUninitializer(LanguageSupport*) in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 426 
    in .LanguageSupport._Initialize(LanguageSupport*) in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 545 
    in .LanguageSupport.Initialize(LanguageSupport*) in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 697 
    --- End of inner exception stack trace --- 
    in .ThrowModuleLoadException(String errorMessage, Exception innerException) in f:\dd\vctools\crt_bld\self_x86\crt\src\minternal.h:line 194 
    in .LanguageSupport.Initialize(LanguageSupport*) in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 707 
    in .cctor() in f:\dd\vctools\crt_bld\self_x86\crt\src\mstartup.cpp:line 749 
    --- End of inner exception stack trace --- 

Есть идеи?

+0

Кроме того: у меня есть те же ploblems после emdedding сторонних библиотек и вы пытаетесь «повторно собрать» только .exe-изображение, используя IlMerge , –

+0

Не используйте ILMerge, используйте ['AppDomain.CurrentDomain.AssemblyResolve' и встроенный resoruce вместо этого] (https://blogs.msdn.microsoft.com/microsoft_press/2010/02/03/jeffrey-richter-excerpt-2 -из-CLR-через-C-третьего издания /). Майк Барнетт, автор ILMerge, комментирует статью и говорит, что если бы он знал об этом трюке, он бы никогда не написал ILMerge в первую очередь. Используя [Fody/Costura] (https://github.com/Fody/Costura), вы можете автоматизировать его во время процесса сборки. –

+0

@Scott поведение AssemblyResolve сильно отличается от ILMerge (рассмотрите возможность доступа к членам с «внутренней» доступностью как только один пример) –

ответ

0

Решение проблемы найдено. Я взял последнюю версию 2.14.1208 из ILMerge, используя NuGet вместо 2.12.803, который можно загрузить с Microsoft

0

ILMerge не может работать с сборками C++/CLI (смешанного режима), однако C++-компоновщик также способен к слиянию через привязку netmodule.

В отличие от компилятора C#, который создает сборку нескольких файлов, когда видит сетевые модули, C++-компоновщик будет генерировать единую файловую сборку.

Выходной файл, созданный линкер будет представлять собой сборку или .netmodule без какой-либо времени выполнения зависимости от любого из .obj или .netmodules, которые были введены в линкер.

Трюк заключается в том, чтобы получить версии .netmodule ваших библиотек. Библиотеки DLL должны содержать все, что требуется .netmodule, но я не уверен, существует ли какой-либо инструмент преобразования. Некоторые ссылки указывают на то, что ildasm + ilasm - это путь, но это может не поддерживать преобразование сборок, запущенных или смешанных.

+0

Я использую Pure MSIL Common Language Runtime Support, исполняемый файл не должен смешиваться с AFAIR. –

Смежные вопросы