我希望这里缺少一些简单的东西。我正在尝试维护两个单独的项目
ProjectName.Core &
ProjectName.Infrastructure
Run Code Online (Sandbox Code Playgroud)
这是在典型的Onion体系结构中完成的,因此我可以松散耦合服务并获得更大的灵活性。基础结构项目引用核心项目。编译后,它们会生成这些DLL
ProjectName.Core.dll &
ProjectName.Infrastructure.dll
Run Code Online (Sandbox Code Playgroud)
但我想让它只生成1个dll。
ProjectName.Infrastructure.dll (or even ProjectName.dll)
Run Code Online (Sandbox Code Playgroud)
我尝试使用ILMerge来执行此操作,但是由于基础结构引用了Core,因此它会引发异常,因为它找不到Core dll。很明显,它本身并不内在。
现在,我需要维护单独的项目,因为我有一些其他引用Core的组合和另一个将结合在一起的项目,例如
ProjectName.Core &
ProjectName.DataAccess &
ProjectName.Web
Run Code Online (Sandbox Code Playgroud)
编辑:我当前的解决方案使用Nant构建脚本调出ILMerge。它成功地合并在一起。但是,当我尝试使用合并的DLL时,它会引发异常,因为它找不到Core库。
<target name="merge.core">
<property name="temp.dir" value="${build.dir}\Temp\"/>
<mkdir dir="${temp.dir}" if="${not directory::exists(temp.dir)}"/>
<property name="tools.dir" value=""${directory::get-current-directory()}\Tools\""/>
<exec program="Tools\ILMerge\ILMerge.exe" workingdir=".">
<arg value="/t:Library"/>
<arg value="/ndebug"/>
<arg value="/out:"${build.dir}\Temp\ProjectName.Infrastructure.dll""/>
<arg value=""${build.dir}ProjectName.Core.dll""/>
<arg value=""${build.dir}Xceed.Compression.dll""/>
<arg value=""${build.dir}ProjectName.Infrastructure.dll""/>
<arg value=""${build.dir}ProjectName.Infrastructure.XmlSerializers.dll""/>
</exec>
<delete file="${build.dir}ProjectName.Core.dll"/>
<delete file="${build.dir}Xceed.Compression.dll"/>
<delete file="${build.dir}ProjectName.Infrastructure.dll"/>
<delete file="${build.dir}ProjectName.Infrastructure.XmlSerializers.dll"/>
<move file="${build.dir}\Temp\ProjectName.Infrastructure.dll" tofile="${build.dir}ProjectName.Infrastructure.dll"/>
<delete dir="${temp.dir}" if="${directory::exists(temp.dir)}"/>
</target>
Run Code Online (Sandbox Code Playgroud)
要更清楚一点。我可以使用核心库之外的对象,但不能使用基础结构库。因为一旦它试图实例化这些对象之一,.NET似乎试图加载该依赖关系但找不到它。
我在Visual Studio中有一个包含5个项目的解决方案.他们是:
Foo.Core:核心功能Foo.Api:生成在核心之上的代码Foo.Web:特定于Web的扩展Foo.Web.Mvc:MVC特定的扩展Newtonsoft.Json:第三方图书馆我想使用ILMerge进行合并Foo.Core,Foo.Api并将Newtonsoft.Json其调用到单个程序集中Foo.这很容易.
我遇到的问题是,Foo.Web并Foo.Web.Mvc都需要引用所有三个合并组件.
如果我引用原始程序集,则在执行ILMerge后它们将具有无效引用.
如果我引用ILMerged程序集,我必须引用一个调试程序集,然后在我打包之前更改它,这似乎并不理想.
我已经尝试创建一个名为的项目Foo,该项目引用3个合并的程序集并用ILmerged程序集替换它自己的输出,但这似乎根本不起作用.
有可靠的方法吗?
目前我知道有两种方法将程序集嵌入到一个应用程序文件中:ILMerge并使用ResolveAssembly事件.
我想知道是否有人在一方面取得了更大的成功.
使用其中任何一个(性能,安全性......)有什么缺点吗?
从我的角度来看,看起来我们应该总是将所有"私有"程序集合并到一个应用程序中,因为当应用程序被视为一个整体时,它会更加干净.
有什么想法吗?
我正在尝试使用ilmerge和此处描述的方法合并两个程序集:
但是,我不想合并的项目引用出现错误...因此,在三个引用的程序集中,我只想合并一个,但是ilmerge似乎不适用于项目引用。
我知道有一个/ lib:选项,但是如何在Ilmerge.CSharp.targets中使它自动化,以便它可与任何项目一起使用?
我在将本地化附属程序集合并到CRM2011的插件DLL中时遇到了一些麻烦.
要么是,要么我不知道如何使用合并后的资源.
我创建了一些插件并创建了一个基本资源文件(默认 - 英语)和一个特定文化(在编写波兰语本地化时,但后来我还需要添加法语).
我确保不要对组件本身进行签名,因为ILMerge将签署完成的组件本身.
这是我用来合并额外附属程序集的命令:
ilmerge /targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319 /log:log.txt /keyfile:KeyFile.snk /out:Plugins.dll DynamicsCRM2011.Plugins.dll pl-PL\DynamicsCRM2011.Plugins.resources.dll
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,插件是在.NET 4.0中,我已经获得了ILMerge所需的.config文件,以便使用所需的程序集进行合并.
生成的文件显示正常,我可以使用CRM插件管理员注册,添加新步骤等等.
但是,它将始终使用默认语言.我试过改变了System.Threading.Thread.CurrentThread.UICulture,但这没有用.当我创建一个ResourceManager类并使用时GetString("ErrorMessage", new System.Globalization.CultureInfo("pl-PL")),我得到Exception了指定的ResourceManager不知道如何处理指定的文化.
我在这里知道这个问题.但是,发布的解决方案似乎是一个旧的解决方案.生成的资源.cs文件不使用ComponentResourceManager.此外,在那里发布的部分代码已被标记为已弃用.
我不确定我现在要做什么,或者如何进一步调试这个,因为我在处理程序集本身方面经验很少.请帮助我控制那些卫星组件.
更新:
我一直在使用沙盒插件一段时间了,因此我不再能够访问诸如此类的东西CurrentCulture(或者至少我无法改变这些东西).我已经尝试再次解决这个问题:我创建了一个简单的插件,在保存新帐户时会触发该插件.没有什么花哨.这是实际的插件代码:
ResourceManager rm = new ResourceManager(typeof(Properties.Resources));
var s = rm.GetString("ErrorAlreadyPosted", new System.Globalization.CultureInfo("pl-PL"));
throw new InvalidPluginExecutionException(s);
Run Code Online (Sandbox Code Playgroud)
该代码不再抛出有关无法找到指定的文化......也是很明显的代码抛出一个最后的异常的异常,但重要的是什么异常消息.我希望它是波兰语.
唉,事实并非如此.返回的字符串GetString仍然是英文.
我用于ILmerge的命令与之前相同,但是/lib指定了参数,以便我不必复制所有CRM SDK dll ...
我正在尝试创建包含Castle.Core的FakeItEasy的合并版本.我读到了有关ILMerge的信息,看起来这是我需要的解决方案.下载并构建FakeItEasy后,我将所需的所有文件(FakeItEasy.dll(.NET4),Castle.Core.dll(.NET4),ilmerge.exe,FakeItEasy.snk)复制到同一文件夹中.然后我运行以下命令:
ilmerge
/keyfile:FakeItEasy.snk
/out:..\FakeItEasy.dll
/t:library
/targetplatform:v4,C:\Windows\Microsoft.NET\Framework\v4.0.30319
FakeItEasy.dll Castle.Core.dll
Run Code Online (Sandbox Code Playgroud)
得到以下结果:
An exception occurred during merging:
An attempt was made to load a program with an incorrect format. (Exception from HRESULT: 0x8007000B)
at System.Compiler.Writer.MscorsnStrongNameSignatureGeneration(String wszFilePath, String wszKeyContainer, Byte[] pbKeyBlob, Int32 cbKeyBlob, IntPtr ppbSignatureBlob, IntPtr pcbSignatureBlob)
at System.Compiler.Writer.WritePE(String location, Boolean writeDebugSymbols, Module module, Boolean delaySign, String keyFileName, String keyName)
at System.Compiler.Writer.WritePE(CompilerParameters compilerParameters, Module module)
at ILMerging.ILMerge.Merge()
at ILMerging.ILMerge.Main(String[] args)
Run Code Online (Sandbox Code Playgroud)
如果我放弃"/keyfile:FakeItEasy.snk",合并的程序集就会很好地创建,但这对我没有帮助,因为我需要一个签名版本.
我也尝试将目标平台指定为:
/targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319
Run Code Online (Sandbox Code Playgroud)
但结果是一样的.
这个问题与我自己的案例有针对性,因为任何拥有本地化应用程序并且必须提供独立EXE的人都有这个问题 - 他们会想要使用ILMerge(或Costura或某些自制程序解决方案)来放置本地化DLL(或任何其他程序集)进入他们的EXE--但一旦他们这样做,他们就不能再调试他们的代码了.VS调试器将拒绝接受为原始EXE生成的原始PDB文件,可能是因为ILMerge步骤更新校验和或更改GUID.
我想知道的是,如果有任何解决方法...就像一些鲜为人知的ILMerge选项,也许吧?它让我感到非常普遍和不必要的调试能力.
我相信在本地化之后调试这样一个应用程序的唯一其他方法是维护一个使用DLL非ILMerged的并行构建选项,这很好,除非您碰巧想要调试本地化代码本身(例如,我).那你真的不走运.谁能想到其他选择?
我也尝试使用Costura,但由于本地化DLL都包含相同名称的资源(并且与主资源AppName.resource相同),因此您只能在引用中添加一个这样的DLL:不允许使用后续的DLL.有没有办法噱头Costura工作?(如果它可以工作,PDB问题可能不会发生,因为组合是视觉工作室构建的一部分..?)
编辑:我正在寻找导致PDB/EXE匹配的想法.我意识到你可以在十六进制编辑器中破解pdb.然而,问题特别询问了如何使系统按预期工作.
我在C#.NET 4.0 Windows服务应用程序中使用ILMerge和Quartz.NET.该应用程序运行良好,而不使用ILMerge,但现在我们即将发布发布,我想将所有DLL组合成一个可执行文件.
问题是,ILMerge似乎工作正常,但是当我运行组合的可执行文件时,它会抛出此异常:
未处理的异常:Quartz.SchedulerException:无法实例化ThreadPool类型"Quartz.Simpl.SimpleThreadPool".---> System.InvalidCastException:无法将类型为"Quartz.Simpl.SimpleThreadPool"的对象强制转换为"Quartz.Spi.IThreadPool".
在Quartz.Util.ObjectUtils.InstantiateType [T](类型型):行0
在Quartz.Impl.StdSchedulerFactory.Instantiate():行0
---内部异常堆栈跟踪---结束
在Quartz.Impl. StdSchedulerFactory.Instantiate()in:
在Quartz.Impl.StdSchedulerFactory.GetScheduler()中的第0行:第0行
有谁知道为什么会这样?我已经浪费了4个多小时,我无法弄明白.如果我不与ILMerge结合,那么一切运行正常(Quartz.dll和Common.Logging.dll位于同一目录中).
我敢肯定有人必须尝试过像这样包装Quartz.net,任何想法吗?
我会尽量简单,如果您需要更多信息,请告诉我.我下载了ILMerge将Newtonsoft.Json.dll合并到我的类库中.我正在使用以下内容从post-build事件命令行调用ILMerge:
"$(ProjectDir)bin\ILMerge.exe" /internalize:"$(ProjectDir)bin\ILMergeIncludes.txt" /out:"$(TargetDir)$(TargetName).all.dll" "$(TargetDir)$(TargetName).dll" "$(TargetDir)*.dll" /target:library /targetplatform:v4,C:\Windows\Microsoft.NET\Framework64\v4.0.30319 /wildcards
Run Code Online (Sandbox Code Playgroud)
在输出窗口中,它显示:
An exception occurred during merging:
ILMerge.Merge: ERROR!!: Duplicate type 'myLibrary.some.class' found in assembly 'myLibrary.all'. Do you want to use the /alllowDup option?
at ILMerging.ILMerge.MergeInAssembly(AssemblyNode a, Boolean makeNonPublic, Boolean targetAssemblyIsComVisible)
at ILMerging.ILMerge.Merge()
at ILMerging.ILMerge.Main(String[] args)
Run Code Online (Sandbox Code Playgroud)
问题是'myLibrary.some.class'不是重复的.
我一直在互联网上寻找线索,所有我发现的是以下2个链接,以及一些网页应用程序,其中人们有复制/粘贴页面,忘了更改类名.
我尝试过使用allowDup选项,但在合并的dll中,它将'myLibrary.some.class'变成'myLibrary.some.random125624.class'.然后我尝试使用allowDup传递'class'然后我得到'class2'然后'class3'然后'class4'的"Duplicate type"错误......似乎没有结束重复类型的数量!
我确信这些类不是重复的,因为命名空间对我的公司和项目非常具体.
有人可以帮忙吗?
我正在构建一个库并拥有一个第三方程序集,无论出于何种原因,我都希望将其打包为嵌入式资源,而不公开为其他DLL。
我的客户端ILM将我的库合并到其可执行文件中。但是,如果我为他们提供带有嵌入式资源的库,则它们会出现“不允许未解析的程序集引用”异常。
由于我不想将我与第三方程序集的所有交互都包装在反射代码中,因此我想将引用保留在库中。
有没有办法告诉ILMerge忽略特定的未解决程序集引用?
ilmerge ×10
.net ×8
c# ×3
localization ×2
.net-4.5 ×1
assemblies ×1
fody-costura ×1
merge ×1
quartz.net ×1