C#中集成DLL庫到自己的exe程序中


原文:http://www.crifan.com/csharp_integrate_dll_library_into_exe_application/

已經實現了下載ST歌曲的小程序,但是由於其中注冊快捷鍵的功能,需要調用額外的一個dll庫,Interop.SHDocVw.dll,所以發布的時候,除了發布一個單獨的exe之外,還需要連帶dll一起發布,很是不爽。

希望將此dll集成到exe中。

【解決過程】

1.從:

如何實現將dll文件集成到exe中

找到:

C# 調用 ilmerge 合並Dll

C#中用ILMerge將所有引用的DLL和exe文件打成一個exe文件

但是個人覺得還是很麻煩,暫且不去使用這類方法,再去找找是否有更好的辦法。

2.后來參考:

C#中怎樣讓引用的.dll文件也集成到生成的.exe文件中

但是去找了下,所引用的dll是Interop.SHDocVw,但是其屬性中,找不到其所說的“嵌入互操作類型”:

找不到 嵌入互操作類型

3.再參考:

VS2010中,無法嵌入互操作類型“……”,請改用適用的接口的解決方法

重新去添加此dll,看看是否可以設置。

但是此處卻找不到Interop.SHDocVw.dll是在哪里引用的了。

然后去代碼中看了看,相關代碼是:

SHDocVw.ShellWindows sws = new SHDocVw.ShellWindows();
然后后來手動刪除該SHDocVw,然后嘗試查找。

后來折騰了半天,終於找到了。

本來是知道了該dll是屬於Microsoft Internet Controls的,所以后來嘗試找此關鍵字,最后是在COM中找到了:

找到了Microsoft Internet Controls的ieframe

添加了后,就可以看到那個SHDocVw了。

4.后來又參考了:

COM Interop, isolation and excluding duplicate references

了解到了,對於SHDocVw的屬性中的Isolated,如果設置為True,則說明當編譯此項目的時候,不拷貝此dll到程序所在目錄。

而此處,看起來,本身就是操作系統自帶的此功能的支持,所以也不需要拷貝了。

所以暫時把其設置為True:

Isolated 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 ==========
然后看了下,再去把Copy Local設置為False,試試,結果還是編譯出錯。

所以,還是改回去,

Isolated為False

就可以正常編譯了,

而Copy Local可以為False的。

5.參考:

Embedding DLLs in a compiled executable

去添加dll到resource中:

add existing file

add shdocvw dll

added Interop_SHDocVw

然后再去設置為 embedded 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,去測試,才可以確定上述方法的真正可行性。

另外,上述方法,還是有點問題,因為先后出現了:

【已 解決】C#項目編譯出錯:TlbImp : error TI0000: System.UnauthorizedAccessException – Access to the path xxx is denied. Microsoft.Common.targets: warning MSB3283: Cannot find wrapper assembly for type library "SHDocVw".

【已 解決】C#項目Clean出錯:Error 1 Resource ‘Interop_SHDocVw’ could not be loaded because the file to which it is linked could not be found


【后記 2】

最后,還是通過自己另一番的折騰,感覺新方法,會更好些:

【已 解決】C#項目Clean出錯:Error 1 Resource ‘Interop_SHDocVw’ could not be loaded because the file to which it is linked could not be found

中的方法類似,把相關的dll文件Interop.SHDocVw.dll,拷貝到單獨的位置,然后再去添加引用此dll:

add reference

selecte res dir dll

然后添加后,SHDocVw的錯誤消失了,就可以正常編譯了,:

added dll then SHDocVw compile ok

此時,就可以:

  • 刪除之前作為資源所添加的Interop.SHDocVw.dll:

    • remove dll in resources

  • 也可以把之前的System.Reflection.Assembly相關的代碼去掉了:

    • remove reflection code

如此做法,目前至少編譯上是OK的,而實際上,應該也是可以正常運行的。

即實現了將dll集成到exe中了。

不過還是需要等待以后的測試才知道最終結果。

后來,經過驗證,此法是行不通的,具體折騰過程參見:

【已 解決】C#編譯出來的程序運行出錯:Unhandled exception has occurred in your application。System.IO.FileNotFoundException: Could not load file or assembly xxx or one of its dependencies. The system cannot find the file specified.

所以,還是需要換之前的方法。

最后,經過測試,還是原先的那個方法,可以實現集成dll到exe中:


【整理】C#中集成dll到exe中的方法

【最新整理: 2013-04-11】

把dll文件添加為資源文件

項目屬性->Resources->Add Resource->Add Existing File:

add existing file 2

然后注意設置過濾規則為 *.*,才能顯示出來dll文件,然后把dll添加進來:

select dll file

把dll文件添加到項目中

【此步驟可選】右擊項目->添加->新建文件夾:

right click project add new folder

再導入對應的dll文件:

add existing dll

然后選擇對應dll,導入即可。

設置項目中的DLL文件為“嵌入的資源”

 其中,如果是英文環境,對應的是把"Build Action"設置為"Embedded Resource"

set to 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庫文件(相關的函數)的目的。

因此,你的程序調用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#編譯出來的程序運行出錯:System.Configuration.ConfigurationErrorsException: Error creating the Web Proxy specified in the ‘system.new/defaultProxy’ configuration section.

但是如果是本地,即當前電腦的硬盤上運行,則不會出現這類問題的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM