【问题】
已经实现了下载ST歌曲的小程序,但是由于其中注册快捷键的功能,需要调用额外的一个dll库,Interop.SHDocVw.dll,所以发布的时候,除了发布一个单独的exe之外,还需要连带dll一起发布,很是不爽。
希望将此dll集成到exe中。
【解决过程】
1.从:
找到:
C#中用ILMerge将所有引用的DLL和exe文件打成一个exe文件
但是个人觉得还是很麻烦,暂且不去使用这类方法,再去找找是否有更好的办法。
2.后来参考:
但是去找了下,所引用的dll是Interop.SHDocVw,但是其属性中,找不到其所说的“嵌入互操作类型”:
3.再参考:
VS2010中,无法嵌入互操作类型“……”,请改用适用的接口的解决方法
重新去添加此dll,看看是否可以设置。
但是此处却找不到Interop.SHDocVw.dll是在哪里引用的了。
然后去代码中看了看,相关代码是:
SHDocVw.ShellWindows sws = new SHDocVw.ShellWindows();
然后后来手动删除该SHDocVw,然后尝试查找。
后来折腾了半天,终于找到了。
本来是知道了该dll是属于Microsoft Internet Controls的,所以后来尝试找此关键字,最后是在COM中找到了:
添加了后,就可以看到那个SHDocVw了。
4.后来又参考了:
COM Interop, isolation and excluding duplicate references
了解到了,对于SHDocVw的属性中的Isolated,如果设置为True,则说明当编译此项目的时候,不拷贝此dll到程序所在目录。
而此处,看起来,本身就是操作系统自带的此功能的支持,所以也不需要拷贝了。
所以暂时把其设置为True:
然后重新编译试试,结果出错:
------ Rebuild All started: Project: downloadSongtasteMusic, Configuration: Debug x86 ------ Build started 9/25/2012 2:43:08 PM. CoreClean: Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\bin\Debug\downloadSongtasteMusic.exe.config". Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\bin\Debug\downloadSongtasteMusic.exe". Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\bin\Debug\downloadSongtasteMusic.pdb". Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\bin\Debug\Interop.SHDocVw.dll". Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\Interop.SHDocVw.dll". Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\downloadSongtasteMusic.csproj.ResolveComReference.cache". Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\downloadSongtasteMusic.completeHint.resources". Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\downloadSongtasteMusic.frmDownloadSongtasteMusic.resources". Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\downloadSongtasteMusic.Properties.Resources.resources". Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\ResGen.read.1.tlog". Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\ResGen.write.1.tlog". Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\downloadSongtasteMusic.exe". Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\downloadSongtasteMusic.pdb". ResolveComReferences: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\TlbImp.exe C:\Windows\SysWOW64\ieframe.dll /namespace:SHDocVw /machine:X86 /out:obj\x86\Debug\Interop.SHDocVw.dll /sysarray /transform:DispRet /reference:"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Visual Studio Tools for Office\PIA\Common\Microsoft.mshtml.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Deployment.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Web.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Windows.Forms.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:C:\Windows\assembly\GAC\stdole\7.0.3300.0__b03f5f7f11d50a3a\stdole.dll CoreResGen: C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\bin\NETFX 4.0 Tools\x64\Tracker.exe @"C:\Users\CLi\AppData\Local\Temp\bdd23727ee984f33b6ad9449e552f963.tmp" /c "C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\ResGen.exe" /useSourcePath /r:"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Visual Studio Tools for Office\PIA\Common\Microsoft.mshtml.dll" /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Deployment.dll /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Web.dll /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Windows.Forms.dll /r:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /r:obj\x86\Debug\Interop.SHDocVw.dll /compile completeHint.resx,obj\x86\Debug\downloadSongtasteMusic.completeHint.resources frmDownloadSongtasteMusic.resx,obj\x86\Debug\downloadSongtasteMusic.frmDownloadSongtasteMusic.resources Properties\Resources.resx,obj\x86\Debug\downloadSongtasteMusic.Properties.Resources.resources CoreCompile: C:\Windows\Microsoft.NET\Framework\v4.0.30319\Csc.exe /noconfig /nowarn:1701,1702 /nostdlib+ /platform:x86 /errorreport:prompt /warn:4 /define:DEBUG;TRACE /reference:"C:\Program Files (x86)\Microsoft Visual Studio 10.0\Visual Studio Tools for Office\PIA\Common\Microsoft.mshtml.dll" /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\mscorlib.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Data.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Deployment.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Drawing.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Web.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Windows.Forms.dll /reference:C:\Windows\Microsoft.NET\Framework\v2.0.50727\System.Xml.dll /reference:obj\x86\Debug\Interop.SHDocVw.dll /debug+ /debug:full /filealign:512 /nowin32manifest /optimize- /out:obj\x86\Debug\downloadSongtasteMusic.exe /resource:obj\x86\Debug\downloadSongtasteMusic.completeHint.resources /resource:obj\x86\Debug\downloadSongtasteMusic.frmDownloadSongtasteMusic.resources /resource:obj\x86\Debug\downloadSongtasteMusic.Properties.Resources.resources /target:winexe /win32icon:songtaste_32x32.ico completeHint.cs completeHint.Designer.cs crifanLib.cs downloadStMusic.cs frmDownloadSongtasteMusic.cs frmDownloadSongtasteMusic.Designer.cs Program.cs Properties\AssemblyInfo.cs Properties\Resources.Designer.cs Properties\Settings.Designer.cs C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2580,9): warning MSB3179: Problem isolating COM reference 'SHDocVw': Components under system file protection should not be isolated. C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2580,9): warning MSB3179: Problem isolating COM reference 'SHDocVw': Registry key 'HKEY_CLASSES_ROOT\CLSID\{eab22ac3-30c1-11cf-a7eb-0000c05bae0b}\MiscStatus' was not imported. C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2580,9): warning MSB3179: Problem isolating COM reference 'SHDocVw': Registry key 'HKEY_CLASSES_ROOT\CLSID\{8856f961-340a-11d0-a96b-00c04fd705a2}\MiscStatus' was not imported. C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2580,9): warning MSB3179: Problem isolating COM reference 'SHDocVw': Out of process servers are not supported C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2580,9): error MSB3179: Problem isolating COM reference 'SHDocVw': Registry key 'HKEY_CLASSES_ROOT\CLSID\{0002df01-0000-0000-c000-000000000046}\InProcServer32' is missing value '(Default)'. C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2580,9): warning MSB3179: Problem isolating COM reference 'SHDocVw': Out of process servers are not supported C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2580,9): error MSB3179: Problem isolating COM reference 'SHDocVw': Registry key 'HKEY_CLASSES_ROOT\CLSID\{d5e8041d-920f-45e9-b8fb-b1deb82c6e5e}\InProcServer32' is missing value '(Default)'. C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2580,9): error MSB3179: Problem isolating COM reference 'SHDocVw': Registry key 'HKEY_CLASSES_ROOT\CLSID\{9ba05972-f6a8-11cf-a442-00a0c90a8f39}\InProcServer32' is missing value '(Default)'. C:\Windows\Microsoft.NET\Framework\v4.0.30319\Microsoft.Common.targets(2580,9): warning MSB3179: Problem isolating COM reference 'SHDocVw': Registry key 'HKEY_CLASSES_ROOT\CLSID\{55136805-b2de-11d1-b9f2-00a0c98bc547}\MiscStatus' was not imported. Build FAILED. Time Elapsed 00:00:01.84 ========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
然后看了下,再去把Copy Local设置为False,试试,结果还是编译出错。
所以,还是改回去,
Isolated为False
就可以正常编译了,
而Copy Local可以为False的。
5.参考:
Embedding DLLs in a compiled executable
去添加dll到resource中:
然后再去设置为 embedded resource:
然后参考:
Embed managed dlls easily in a .NET assembly
的代码,添加代码为:
namespace downloadSongtasteMusic { class songtaste { ... public songtaste() { crl = new crifanLib(); AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve); } System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { string dllName = args.Name.Contains(",") ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll",""); dllName = dllName.Replace(".", "_"); if (dllName.EndsWith("_resources")) return null; System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly()); byte[] bytes = (byte[])rm.GetObject(dllName); return System.Reflection.Assembly.Load(bytes); }
如此,也不知道是否可以。
【总结】
等待以后确认,暂时不知道是否可行。
因为之前试过了,即使把downloadSongtasteMusic.exe同文件夹下的Interop.SHDocVw.dll删除掉,也还是可以运行的,所以此处无法测试。
等以后有空换个电脑测试测试此法是否可用。
【后记 1】
后来对于上述方法集成的exe,拿到别的另外一台同样配置和系统的机子上测试,是可以运行的。
但是猜测还是由于同样是64位win7,所以肯定是可以运行的。
还需要找找其他不同系统,比如xp,去测试,才可以确定上述方法的真正可行性。
另外,上述方法,还是有点问题,因为先后出现了:
和
【后记 2】
最后,还是通过自己另一番的折腾,感觉新方法,会更好些:
同
中的方法类似,把相关的dll文件Interop.SHDocVw.dll,拷贝到单独的位置,然后再去添加引用此dll:
然后添加后,SHDocVw的错误消失了,就可以正常编译了,:
此时,就可以:
如此做法,目前至少编译上是OK的,而实际上,应该也是可以正常运行的。
即实现了将dll集成到exe中了。
不过还是需要等待以后的测试才知道最终结果。
后来,经过验证,此法是行不通的,具体折腾过程参见:
所以,还是需要换之前的方法。
最后,经过测试,还是原先的那个方法,可以实现集成dll到exe中:
【整理】C#中集成dll到exe中的方法
【最新整理: 2013-04-11】
把dll文件添加为资源文件
项目属性->Resources->Add Resource->Add Existing File:
然后注意设置过滤规则为 *.*,才能显示出来dll文件,然后把dll添加进来:
把dll文件添加到项目中
【此步骤可选】右击项目->添加->新建文件夹:
再导入对应的dll文件:
然后选择对应dll,导入即可。
设置项目中的DLL文件为“嵌入的资源”
然后,在左边的项目列表中,点击对应的dll文件,右键选择属性,设置“生成操作”为“嵌入的资源”:
其中,如果是英文环境,对应的是把"Build Action"设置为"Embedded Resource"
表示,此项目会把此dll集成到生成的(exe)文件中,以此实现dll先集成到生成的exe文件本身中。
通过Reflection代码实现载入内置的(dll)资源文件
把下面代码,添加到你的项目的主类中:
... namespace downloadSongtasteMusic { class songtaste { ... public songtaste() { ... AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve); } System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) { string dllName = args.Name.Contains(",") ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll", ""); dllName = dllName.Replace(".", "_"); if (dllName.EndsWith("_resources")) return null; System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly()); byte[] bytes = (byte[])rm.GetObject(dllName); return System.Reflection.Assembly.Load(bytes); } ... } }
如此,其会在主程序初始化的时候,就去把内在的那些资源文件,此处包括你所添加的dll文件,载入尽量,实现了载入dll库文件(相关的函数)的目的。
因此,你的程序调用dll中的函数,也才能找到合适的函数,而不会出现找不到函数,找不到dll库的问题。
至此,就实现了,C#中将dll集成到exe中的目的了。
注意事项:
1.把dll添加作为资源文件,之前以为是可以省略的呢,后来证实,这一步是必不可少的。否则,也是无法把dll集成进来的。
2. 对于上述,在类初始化函数中的,要添加的那句:
AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve);
千万不能忘了!!!
否则就像我此处,调试了半天,最终也没有实现对应的集成dll到exe的效果。
最后是找到此处忘了添加这句,导致没有集成dll成功。
所以,千万不要犯和我此处同样的错误。
3.只是把dll导入为资源(res)文件后,在项目文件列表中,是看不到对应的文件的;
只能是,另外再导入现存的dll文件,才能在项目文件列表中,看到对应的dll,才能选择该dll,设置为嵌入的资源;
4.不同的类,比如一个winForm类frmFiverrComScraper.cs,另外一个我自己的库crifanLib.cs,
如果使用到了对应的dll(中的类),那么,分别都要在自己的类的构造函数中,加入对应的
AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve);
和
System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {…..}
部分的代码的。
当然,多个类,可以通用一份CurrentDomain_AssemblyResolve的代码实现。
5.如果exe是在网上邻居/网络共享中运行的话,可能会出现问题,详情参考:
但是如果是本地,即当前电脑的硬盘上运行,则不会出现这类问题的。
转载请注明:在路上 » 【已解决】C#中集成DLL库到自己的exe程序中