【问题】
已经实现了下载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是在哪里引用的了。
然后去代码中看了看,相关代码是:
1 | 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:
然后重新编译试试,结果出错:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | ------ 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
的代码,添加代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | 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)资源文件
把下面代码,添加到你的项目的主类中:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | ... 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. 对于上述,在类初始化函数中的,要添加的那句:
1 | 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程序中