标签: com

我想学习COM.我该怎么办?

我是一名刚毕业的计算机科学学士.就像今天的大多数学校一样,他们不再教学生C或推进C++(只有C++的入门课程......有教学指针).课程中规定的标准编程语言是C#(.NET堆栈).

就在最近,我被聘为初级软件开发人员.95%的代码库都是用C++编写的,我们的产品使用的是COM/DCOM.另外5%是在.NET中.我目前的职责是维护一个用.NET(ASP.NET)编写的项目,我不需要学习C++和其他技术YET.但我想尽快学习COM,以便我可以帮助其他项目.

所以我正在寻求这个社区的建议,我将如何学习COM.我目前的问题如下:

  1. 任何所需的阅读?(必备主题)
  2. 学习COM基础知识的好网站?
  3. 一种简单程序,真正体会COM的"目的"(也许是一个聊天程序?)

谢谢!:)

PS:我应该将其标记为社区维基吗?

c++ com

11
推荐指数
4
解决办法
4390
查看次数

如何在VB.NET中安装并在Automation Servers列表中注册的用于Excel的COM Server for Excel?

版本

Excel 2007,Windows Vista,VB.NET,带有.NET 3.5 sp2的Visual Studio 2008,MSI安装程序包.

我想做什么

我有一个用VB.NET编写的Excel UDF.它作为COM服务器公开,因为您无法直接在.NET语言中创建Excel UDF.安装是一个真正的痛苦,因为没有任何安装设置似乎正确; 它们都没有为您提供一个安装包,它将COM服务器放在客户端计算机上,注册了服务器,注册了类型库,并且组件在Excel 2007的自动化服务器列表中可见.

我试过的

以下是类型库的安装设置,它们的缺陷在编译时和安装时显而易见:

vsdrfComSelfReg

  • 在编译安装项目期间没有警告
  • 模块xxx.tlb无法注册.HRESULT -2147024703
  • 组件的ProgID和GUID在注册表中设置,但该组件未出现在自动化服务器列表中

vsdrfDoNotregister

  • 编译期间没有警告
  • 安装工作,但TLB当然没有注册

vsdrfCOM

  • 编译时警告:警告:无法为名为"xxx.tlb"的文件创建注册信息
  • 安装期间未注册类型库

正确的设置应该是vsdrfCOM,如解释在这里:

问:任何人都可以告诉vsdrfCOM在Visual Studio的安装项目中的含义吗?当我在安装项目中添加文件的属性中检查属性"注册"时,它可用.

答:这意味着Visual Studio将在构建时提取COM注册数据并将其放入MSI文件(主要是MSI文件的注册表表,但也包括类表).因此,当您安装它时,您的代码不需要自行注册,因为文件被复制到磁盘并创建了注册表项.它还将通过向MSI的TypeLib表添加条目来创建类型库注册.

许多困难似乎都是针对Vista的.特别是,使用REGCAP实用程序.TLB文件生成.REG文件在Vista中不起作用.如果不是这样,也许这个建议会很有用.相反,它生成空的.REG文件.

我已经尝试了StackOverflow帖子中的所有建议.该帖子对技术问题有很好的描述:

"引用"对话框中的条目来自HKCR\TypeLib注册表项,而不是来自HKCR\CLSID.如果您的程序集没有显示在"引用"对话框中,但已编译的DLL仍然可以使用您的COM程序集,则表示已为程序集正确注册了类和接口,但类型库本身没有.

这个问题

任何人都知道如何使安装注册组件和类型库?我无法访问Windows XP计算机.


详细说明为什么这很糟糕

任何编译的代码都不需要.TLB来调用它.我没有像你一样尝试部署Excel自动化加载项,但我的猜测是UDF应该加载并运行得很好.

它在Excel中不太像.

  • 用户打开工作表并尝试引用UDF.找不到它,因为未加载DLL.失败
  • 用户转到"主页"|"Excel选项"|"加载项"|"Excel加载项+转到",并且"加载项"对话框中未列出COM服务器.失败
  • 然后,用户按下自动化服务器以获取可用自动化服务器的列表.DLL不在那里.失败
  • 用户返回"加载项"对话框并选择"浏览",导航到安装目录,然后选择DLL("XXX不是有效的加载项")或类型库("您选择的文件不包含新的Automation Server,或者您没有足够的权限......").失败

据我所知,用户必须从命令行运行regasm.exe才能使Excel UDF/COM服务器可用.如何告诉人们从命令行运行regasm以安装Excel的加载项?


编辑2009-10-04

Mike的评论和指示非常棒.我不知道的关键是安装程序有一个内置的注册表编辑器,用于添加注册表项.哦,Microsoft安装程序没有调用带有属性ComRegisterFunctionAttribute安装函数.我已经从他引用的来源获得了关于编写安装程序功能的指示.

.net com excel installation

11
推荐指数
1
解决办法
1万
查看次数

为什么我会使用"Both"COM线程模型而不是"Free"?

根据这篇文章,如果我用"Both"或"Free"线程模型注册我的COM对象,该对象必须完全是线程安全的.具体而言,必须同步对全局共享变量的所有访问,并且还必须同步对成员变量的所有访问.这是很多努力.

现在我明白能够将我的对象注册为使用"Free"线程模型是有利的,并且可能值得付出使其完全线程安全的代价.但是为什么我要做所有相同的操作并使用"Both"线程模型注册我的对象呢?有什么好处?如何选择"两者"和"免费"?

windows com multithreading com-interop

11
推荐指数
1
解决办法
4985
查看次数

虚空**的含义是什么?

当我在COM中开发时,我总是看到(void**)类型转换如下.

QueryInterface(/* [in] */ REFIID riid,/* [out] */ void** ppInterface)
Run Code Online (Sandbox Code Playgroud)

它的确切含义是什么?

恕我直言,它告诉编译器不要强制执行类型验证,因为在编译时客户端代码不知道ppInterface指向的类型.

谢谢~~~

更新1

我这样理解:

void*p表示 AnyType*p

void**pp 表示指向AnyType的指针*

更新2

如果void**pp表示"指向void*的指针",那么编译器在看到它时会做什么检查?

c c# c++ com

11
推荐指数
3
解决办法
876
查看次数

为什么每个成功的QueryInterface()调用后跟Release()调用?

为什么QueryInterface()呼叫总是跟着Release()呼叫?例如,我看过MSDN的示例代码如下:

HRESULT hr = S_OK;
CDecoder *pObj = new CDecoder(&hr);

if (SUCCEEDED(hr))
{
    *ppv = NULL;
    hr = pObj->QueryInterface(riid, ppv);
}
pObj->Release();
return hr;
Run Code Online (Sandbox Code Playgroud)

有人可以解释Release()这里打电话的意图吗?

c++ com interface object queryinterface

11
推荐指数
2
解决办法
1万
查看次数

在C#中通过COM RCW对象检测跨线程编组

我正在处理大型多线程C#应用程序处理COM互操作串.其他开发人员和我有充分的机会不小心从MTA线程调用单线程公寓(STA) COM对象,并从他们未创建的STA线程.性能低迷,跨线程编组是主要的嫌疑.

是否有一个很好的方法来测试跨公寓编组?更好的是,是否有一种防御性编程技术来测试给定的COM对象属于这个线程的公寓?

我最接近的是一个关于可疑代码的防御声明:

Debug.Assert(Thread.CurrentThread.GetApartmentState() == ApartmentState.STA);
suspiciousComInterface.SomeMethod();
Run Code Online (Sandbox Code Playgroud)

虽然如果我们的BackgroundWorker线程正在调用STA对象,这将警告我们,我特别担心STA线程正在使用在另一个STA线程中创建的COM运行时可调用包装器(RCW)对象.

一个在线源认为,这是不可能的(http://www.pcreview.co.uk/forums/detecting-cross-apartment-com-calls-t2450589.html),在CLR掩盖了太多的COM代理的使对象在高级别可访问的对象.

我无法相信这是唯一的答案.谢谢!

c# com multithreading .net-4.0 marshalling

11
推荐指数
1
解决办法
1510
查看次数

使用DLL中的COM对象而无需注册

是否可以使用DLL中的COM对象而无需在C++中注册而不是托管代码?

c++ com dll

11
推荐指数
3
解决办法
6763
查看次数

使用C++"operator new"而不是CoCreateinstance来创建COM对象是否安全?

这可能是一个菜鸟COM问题,但谷歌搜索引发的问题多于提供答案:

对于本地COM实例,使用"operator new"而不是CoCreateInstance是否安全?

我做了什么:

  1. 我 通过使用公共继承实现了IOperationsProgressDialog接口 http://msdn.microsoft.com/en-us/library/windows/desktop/bb775368(v=vs.85).aspx,从而也实现了IUnknown接口.

  2. 我通过"new RecyclerProgressCallback"创建了一个实例,并将其放入COM-Ptr进行终身管理."RecyclerProgressCallback"是我派生类的名称.

  3. 我在IFileOperation :: SetProgressDialog中使用此实例 http://msdn.microsoft.com/en-us/library/windows/desktop/bb775803(v=vs.85).aspx

简介:我的方法似乎"似乎"起作用,但我不相信它,围绕COM对象创建的过多令人不安的信息只依赖于可观察行为.

是否有任何微妙的风险,谬误或其他问题?谢谢!

c++ com

11
推荐指数
1
解决办法
731
查看次数

在没有ATL的情况下实现COM IDispatch

我正在编写一个Excel RTD服务器实现,我被困在一个实现的coclass的样板上IDispatch.我无法访问ATL,但我使用的是ActiveQt,虽然我对如何在原始C或C++中执行此操作感兴趣.如何正确实现IDispatchCOM服务器中的方法?

一如既往,文档非常糟糕.到目前为止我所读的内容如下:

这种LoadTypeLib()方法似乎适合COM 客户端访问某些库的类型信息,而不适用于尝试内省自身的COM服务器.我对么?

c c++ com qt

11
推荐指数
2
解决办法
5377
查看次数

截至今天,使用COM对象的正确方法是什么?

这是一个非常常见的问题,我决定问这个问题,因为这个问题在今天可能会有不同的答案.希望这些答案有助于理解使用COM对象的正确方法.就个人而言,在对此主题发表不同意见后,我感到非常困惑.

在过去的5年中,我曾经使用COM对象,规则对我来说非常清楚:

  1. 在代码行中使用单个句点.使用多个句点在场景后面创建无法明确释放的临时对象.
  2. 不要使用foreach,而是使用for循环,并在每次迭代时释放每个项目
  3. 不要调用FInalReleaseComObject,而是使用ReleaseComObject.
  4. 不要使用GC释放COM对象.GC意图主要用于调试用法.
  5. 以与创建对象相反的顺序释放对象.

你们中的一些人在阅读完最后一行后可能会感到沮丧,这就是我所知道的如何正确创建/发布Com对象,我希望能得到更清晰无误的答案.

以下是我在这个主题上找到的一些链接.他们中的一些人告诉他们需要调用ReleaseComObject而其中一些不需要.

"...在VSTO场景中,您通常不必使用ReleaseCOMObject......."

"...您应该使用此方法释放包含引用的基础COM对象......"

更新:

这个问题被标记为过于宽泛.根据要求,我将尝试简化并提出更简单的问题.

  1. 使用COM对象或调用GC是否正确时,是否需要ReleaseComObject?
  2. VSTO方法是否会改变我们以前使用COM对象的方式?
  3. 我写的上述哪些规则是必需的,哪些是错的?还有其他人吗?

.net c# vb.net com excel

11
推荐指数
1
解决办法
2041
查看次数