免注册COM在使用时要使用文件清单(manifest文件),文件清单在使用时可分为两种:
1.程序清单:
指明程序包含哪些依赖组件。
C\C++的程序清单信息可在项目属性中编辑,用于自动生成。
C#的程序清单暂时没找到自动生成的办法,使用VS本身提供的清单生成工具生成的清单无法正确使用。因此只能手动编写。
2.组件清单:
指明组件(DLL)的COM相关信息,GUID等信息,基本和注册在注册表中的信息一致。
组件清单可用VS工具mt.exe来生成,具体参看MSDN。
用mt.exe时有时会需要用到tlb文件,如果是C#的COM的话,则可以用Tlbexp.exe(类型库导出程序)从DLL生成TLB文件,一般不会这样用,C#的话一般就是直接指明为托管程序集,直接从DLL组件清单。C++的COM的话,可以用从DLL嵌入的资源中获取。
使用文件清单可以通过以下几种方式:
1.嵌入,这个需要在工程属性中设置。
2.使用对应命名的清单文件。例如:
程序清单:
文件:1.exe
清单:1.exe.manifest
组件清单:
文件:1.dll
清单:1.manifest
红字部分要一致。并且请将对应的文件和清单放置在一起。
3.使用Activation Context API加载指定清单。(这个还未有研究)
使用前两种方法时,要求被调用的dll与调用者在同一目录下。也有说是在调用者的子目录下也可以。
实例代码可以在下面下载:
http://download.csdn.net/detail/u011623102/8060055
####################################################################################################
2014-12-11 更新
之前写的Com免注册方法,Dll文件必须在执行的应用程序同目录或子目录下,在实际使用中有太大的局限性。
其实在C#中要是能够知道所要掉的Com的位置,其实是可以用tlbimp.exe工具将Com组件转换成一个托管DLL。在引用此DLL就可以了。
C++调用C#的COM组件,最好的方法还是去使用Activation Context API加载指定清单。
使用的一个实例是在头文件中
#import “Dll或TLB"
看文档好像应该是还要加一个宏,我自己用的时候是建立的使用MFC的控制台程序,所以直接引用就可以用。
关键的结构是ACTCTX
ACTCTX actCtx;
memset((void*)&actCtx, 0, sizeof(ACTCTX));
actCtx.cbSize = sizeof(ACTCTX);
actCtx.lpSource = _T("指定路径的manifest文件"); //直接使用manifest文件时只设置这个就可以了
HANDLE hCtx = ::CreateActCtx(&actCtx);
if (hCtx == INVALID_HANDLE_VALUE)
{
cout << "CreateActCtx returned: INVALID_HANDLE_VALUE"
<< endl;
}
else
{
ULONG_PTR cookie;
if (::ActivateActCtx(hCtx, &cookie))
{
// previous compound statement goes here...
//像注册了COM一样调用就好
::DeactivateActCtx(0, cookie);
}
}
好像ACTCTX中的lpSource字段还可以指定为DLL或是EXE
这样使用时需要用lpResourceName字段来指定嵌入的哪一个资源是清单资源
自此暂时够用了,ACTCTX指定DLL之后有需要在研究了