【问题】
已经实现了下载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是在网上邻居/网络共享中运行的话,可能会出现问题,详情参考:
但是如果是本地,即当前电脑的硬盘上运行,则不会出现这类问题的。
博主真牛,这么耐心,佩服
感谢博主的折腾精神,
在vs08下没法用嵌入资源的方式,可直接在项目上添加现用项,其它参考这篇博文就ok了。http://www.cnblogs.com/kui2/archive/2012/11/29/embedded-dll.html
C#中怎样让引用的.dll文件也集成到生成的.exe文件中
但是去找了下,所引用的dll是Interop.SHDocVw,但是其属性中,找不到其所说的“嵌入互操作类型”:
============
这个需要.net framework 4.0以上才支持
多谢提醒。
话说,我之前写程序,也是尽量使用.NET 2.0的,希望尽量保持向后兼容性。
当然,有机会使用.NET 4.0,也可以利用更多的新特性。算是各有优劣了。
我们现在拿.net做个互联网产品,也是基于2.0框架。其他版本框架太大了。
忍不住吐槽下微软,你就不能在推出xp sp3 补丁的时候,把.net 框架也打进去?真不知道微软是怎么想的。