原文:http://www.crifan.com/csharp_integrate_dll_library_into_exe_application/
已經實現了下載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();
后來折騰了半天,終於找到了。
本來是知道了該dll是屬於Microsoft Internet Controls的,所以后來嘗試找此關鍵字,最后是在COM中找到了:
添加了后,就可以看到那個SHDocVw了。
4.后來又參考了:
COM Interop, isolation and excluding duplicate references
了解到了,對於SHDocVw的屬性中的Isolated,如果設置為True,則說明當編譯此項目的時候,不拷貝此dll到程序所在目錄。
而此處,看起來,本身就是操作系統自帶的此功能的支持,所以也不需要拷貝了。
所以暫時把其設置為True:
然后重新編譯試試,結果出錯:
1 ------ Rebuild All started: Project: downloadSongtasteMusic, Configuration: Debug x86 ------ 2 Build started 9/25/2012 2:43:08 PM. 3 CoreClean: 4 Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\bin\Debug\downloadSongtasteMusic.exe.config". 5 Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\bin\Debug\downloadSongtasteMusic.exe". 6 Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\bin\Debug\downloadSongtasteMusic.pdb". 7 Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\bin\Debug\Interop.SHDocVw.dll". 8 Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\Interop.SHDocVw.dll". 9 Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\downloadSongtasteMusic.csproj.ResolveComReference.cache". 10 Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\downloadSongtasteMusic.completeHint.resources". 11 Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\downloadSongtasteMusic.frmDownloadSongtasteMusic.resources". 12 Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\downloadSongtasteMusic.Properties.Resources.resources". 13 Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\ResGen.read.1.tlog". 14 Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\ResGen.write.1.tlog". 15 Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\downloadSongtasteMusic.exe". 16 Deleting file "D:\tmp\tmp_dev_root\downloadSongtasteMusic\downloadSongtasteMusic\downloadSongtasteMusic\obj\x86\Debug\downloadSongtasteMusic.pdb". 17 ResolveComReferences: 18 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 19 CoreResGen: 20 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 21 CoreCompile: 22 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 23 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. 24 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. 25 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. 26 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 27 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)'. 28 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 29 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)'. 30 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)'. 31 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. 32 33 Build FAILED. 34 35 Time Elapsed 00:00:01.84 36 ========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
所以,還是改回去,
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 namespace downloadSongtasteMusic 2 { 3 class songtaste 4 { 5 ... 6 public songtaste() 7 { 8 crl = new crifanLib(); 9 10 AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve); 11 } 12 13 System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 14 { 15 string dllName = args.Name.Contains(",") ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll",""); 16 17 dllName = dllName.Replace(".", "_"); 18 19 if (dllName.EndsWith("_resources")) return null; 20 21 System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly()); 22 23 byte[] bytes = (byte[])rm.GetObject(dllName); 24 25 return System.Reflection.Assembly.Load(bytes); 26 }
【總結】
等待以后確認,暫時不知道是否可行。
因為之前試過了,即使把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文件為“嵌入的資源”
其中,如果是英文環境,對應的是把"Build Action"設置為"Embedded Resource"
表示,此項目會把此dll集成到生成的(exe)文件中,以此實現dll先集成到生成的exe文件本身中。
通過Reflection代碼實現載入內置的(dll)資源文件
把下面代碼,添加到你的項目的主類中:
1 ... 2 3 namespace downloadSongtasteMusic 4 { 5 class songtaste 6 { 7 ... 8 public songtaste() 9 { 10 ... 11 12 AppDomain.CurrentDomain.AssemblyResolve +=new ResolveEventHandler(CurrentDomain_AssemblyResolve); 13 } 14 15 System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 16 { 17 string dllName = args.Name.Contains(",") ? args.Name.Substring(0, args.Name.IndexOf(',')) : args.Name.Replace(".dll", ""); 18 19 dllName = dllName.Replace(".", "_"); 20 21 if (dllName.EndsWith("_resources")) return null; 22 23 System.Resources.ResourceManager rm = new System.Resources.ResourceManager(GetType().Namespace + ".Properties.Resources", System.Reflection.Assembly.GetExecutingAssembly()); 24 25 byte[] bytes = (byte[])rm.GetObject(dllName); 26 27 return System.Reflection.Assembly.Load(bytes); 28 } 29 30 ... 31 } 32 }
因此,你的程序調用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是在網上鄰居/網絡共享中運行的話,可能會出現問題,詳情參考:
但是如果是本地,即當前電腦的硬盤上運行,則不會出現這類問題的。