用C#创建COM对象

原创 2004年07月09日 13:45:00
第一部分:用C#创建简单的COM对象

  COM对象是ClassLibrary类,它生成DLL文件。要在VS开发环境中创建一个简单的COM对象,我们可以依次选择“文件”->;“新创建”->;“工程”->;“VisualC#工程”->;“类库”,然后创建一个名字为Database_COMObject的工程。

  需要注意的是:在COM中调用VC#对象需要下面的条件:

  ·类必须是public性质。
  ·特性、方法和事件必须是public性质的。
  ·特性和方法必须在类接口中定义。
  ·事件必须在事件接口中定义。

  不是在这些接口中定义的public性质的类成员不能被COM访问,但它们可以被其他的.NET Framework对象访问。要让COM能够访问特性和方法,我们必须在类接口中定义它们,使它们具有DispId属性,并在类中实现这些特性和方法。这些成员定义时的顺序也就是它们在COM中顺序。要让COM访问类中的事件,必须在事件接口中定义这些事件,并赋予它们DispId属性。事件接口不应当由类完成,类只实现类接口(它可以实现不止一个接口,但第一个接口是缺省接口),应当在缺省接口中实现需要让COM访问的方法和特性,方法和特性必须被标识为public性质,并符合在类接口中的定义。需要让COM访问的事件也在缺省的类接口中完成,它们也必须被标识为public性质,并符合事件接口中的定义。

  在接口名字之前,每个接口需要一个GUID特性。要生成变个唯一的Guid,需要运行guidgen.exe工具软件,并选择“注册表格式” 下面是一个类界面:

[Guid(";694C1820-04B6-4988-928F-FD858B95C880";)]
public interface DBCOM_Interface
{
[DispId(1)]
void Init(string userid , string password);
[DispId(2)]
bool ExecuteSelectCommand(string selCommand);
[DispId(3)]
bool NextRow();
[DispId(4)]
void ExecuteNonSelectCommand(string insCommand);
[DispId(5)]
string GetColumnData(int pos);
}

  COM事件接口:

// 事件接口Database_COMObjectEvents
[Guid(";47C976E0-C208-4740-AC42-41212D3C34F0";),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface DBCOM_Events
{
}

  下面是实际的类定义:

[Guid(";9E5E5FB2-219D-4ee7-AB27-E4DBED8E123E";),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(DBCOM_Events))]
public class DBCOM_Class : DBCOM_Interface
{

  需要注意的是,在类的前面,需要设置下面的特性:

ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(DBCOM_Events))]

  ClassInterfaceType.None表示没有为该类生成类接口,如果没有明确地实现接口,类只能通过IDispatch提供后期绑定访问。用户希望通过明确地由类实现的接口使外部对象能够访问类的功能,这也是推荐的ClassInterfaceAttribute的设置。

  ComSourceInterfaces(typeof(DBCOM_Events))]确定许多作为COM事件向外部对象提供的接口。在本文的例子中,我们不对外部对象开放任何事件。

  下面是COM对象完整的源代码:

using System;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
using System.Data.SqlClient;
using System.Windows.Forms ;

namespace Database_COMObject
{
[Guid(";694C1820-04B6-4988-928F-FD858B95C880";)]
public interface DBCOM_Interface
{
[DispId(1)]
void Init(string userid , string password);
[DispId(2)]
bool ExecuteSelectCommand(string selCommand);
[DispId(3)]
bool NextRow();
[DispId(4)]
void ExecuteNonSelectCommand(string insCommand);
[DispId(5)]
string GetColumnData(int pos);
}

// 事件接口Database_COMObjectEvents
[Guid(";47C976E0-C208-4740-AC42-41212D3C34F0";),
InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface DBCOM_Events
{
}


[Guid(";9E5E5FB2-219D-4ee7-AB27-E4DBED8E123E";),
ClassInterface(ClassInterfaceType.None),
ComSourceInterfaces(typeof(DBCOM_Events))]
public class DBCOM_Class : DBCOM_Interface
{
private SqlConnection myConnection = null ;
SqlDataReader myReader = null ;

public DBCOM_Class()
{
}

public void Init(string userid , string password)
{
try
{
string myConnectString = ";user id=";+userid+";;password=";+password+
";;Database=NorthWind;Server=SKYWALKER;Connect Timeout=30";;
myConnection = new SqlConnection(myConnectString);
myConnection.Open();
MessageBox.Show(";CONNECTED";);
}
catch(Exception e)
{
MessageBox.Show(e.Message);
}
}

public bool ExecuteSelectCommand(string selCommand)
{
if ( myReader != null )
myReader.Close() ;

SqlCommand myCommand = new SqlCommand(selCommand);
myCommand.Connection = myConnection;
myCommand.ExecuteNonQuery();
myReader = myCommand.ExecuteReader();
return true ;
}

public bool NextRow()
{
if ( ! myReader.Read() )
{
myReader.Close();
return false ;
}
return true ;
}

public string GetColumnData(int pos)
{
Object obj = myReader.GetValue(pos);
if ( obj == null ) return ";"; ;
return obj.ToString() ;
}

public void ExecuteNonSelectCommand(string insCommand)
{
SqlCommand myCommand = new SqlCommand(insCommand , myConnection);
int retRows = myCommand.ExecuteNonQuery();
}

}
}

  在创建COM对象前,我们必须向COM Interop注册该对象。右击方案管理器中的工程名字,点击快捷菜单上的“属性”选项,然后再点击“配置”->;“创建”,扩展output小节,将Register for COM Interop选项的值设置为true。这样,一个COM对象就能够与可管理性应用程序进行交互。

  为了使COM对象能够被外部对象调用,类库组合必须有一个强名字。创建强名字需要用到SN.EXE名字:

sn -k Database_COM_Key.snk
打开AssemblyInfo.cs,并修改下面一行的内容:
[assembly: AssemblyKeyFile(";Database_COM_Key.snk";)]

  创建对象。创建对象会生成一个可以被导入到可管理性或非可管理性代码中的类库。

  第二部分:使用Visual C++创建访问COM对象的客户端软件

  ·使用VC++开发环境创建一个简单的工程。
  ·使用#import directive导入类型库。
  ·在界面中创建一个Smart Pointer,从接口中执行COM类提供的功能。确保在应用程序加载时添加CoInitialize()调用:

CoInitialize(NULL);

Database_COMObject::DBCOM_InterfacePtr p(__uuidof(Database_COMObject::DBCOM_Class));
db_com_ptr = p ;
db_com_ptr->;Init(";scott"; , ";tiger";);

  下面的代码对Customers数据库表执行一个SQL命令,返回给定ID的客户的信息:

char cmd[1024];
sprintf(cmd , ";SELECT COMPANYNAME , CONTACTNAME ,
CONTACTTITLE , ADDRESS FROM CUSTOMERS WHERE CUSTOMERID = '%s'"; , m_id );
const char *p ;

bool ret = db_com_ptr->;ExecuteSelectCommand(cmd);

if ( ! db_com_ptr->;NextRow() ) return ;

_bstr_t mData = db_com_ptr->;GetColumnData(3);
p = mData ;
m_address = (CString)p ;

C#中调用COM对象

C#中调用COM对象
  • u011162260
  • u011162260
  • 2015-05-22 20:42:29
  • 1894

c#实现和vb调用createobject()类似方法创建com对象,调用method和property

VB中可以直接用CreateObject("ProgID"或者"CLSID")就可以创建com对象,然后直接使用它的方法和属性,但是c#网上资料很少 C#中类似 CreateObject 的方法就是...
  • xt_chaoji
  • xt_chaoji
  • 2012-04-13 16:00:17
  • 3770

创建VirtualBoxClient COM对象失败

由于编者水平有限,文中难免会有错误和疏漏,请各位读者能提出宝贵建议或给予指正,可在博文下评论指出,我会及时改进,在此先感谢各位。   本文是自己学习所做笔记,欢迎转载,但请注明出处:http://bl...
  • YiJuanXia
  • YiJuanXia
  • 2016-03-08 09:37:26
  • 2662

创建virtualboxclient com对象失败最简单有效的解决方案

右键VirtualBox的桌面快捷方式,选择属性 选到兼容性选项卡,勾选“以兼容模式运行这个程序” 下拉框选择Windows Server 2008 (Service Pack 1) 再勾选“以管理员...
  • danshenxiaobang
  • danshenxiaobang
  • 2017-06-06 14:16:53
  • 1136

virtualbox创建com对象失败(解决方法)

virtualbox创建com对象失败(解决方法) 试过网上的好几个方法都不行,最后结合了两种办法才搞定。 方法一:(不能完全解决问题) ①对VirtualBox的图标点击右键->属性->兼容性; ②...
  • mingmingzhizhonging
  • mingmingzhizhonging
  • 2016-03-10 14:09:24
  • 23068

创建 VirtualBoxClient COM 对象失败.应用程序将被中断

1、正在玩着VirtualBox虚拟机,后来出现虚拟机未响应问题 就直接强制退出、重启; 然而打开时却出现了以下问题: 2、解决方法: 打开计算机C:\Windows\System32 ;找...
  • a_ssimi
  • a_ssimi
  • 2016-07-23 11:26:20
  • 3628

C#托管环境下释放COM对象

开发小组在VS2005 c++环境中,使用ATL编写了一组COM组件,在VS 2005 C#项目中引入后使用,浏览地图,使用一段时间后,发现无法正常显示地图了,显示有些线无法绘制、然后一些多边形无法绘...
  • ErikLiu
  • ErikLiu
  • 2009-12-08 09:29:00
  • 2994

VirtualBox提示严重错误,创建 COM 对象失败的问题

这个问题出现在我启动VitualBox的时候,由于最近在使用这个虚拟机,又由于磁盘空间不足导致了虚拟机宕掉,清理空间再次启动后出现该错误,不多说,直接上问题解决方法,希望能帮助到遇到同样问题的朋友。一...
  • Alvin_CSDN_blog
  • Alvin_CSDN_blog
  • 2017-03-14 12:13:24
  • 1708

COM对象的创建原理

笔者学习COM原理有一段时间了,但是在创建COM对象时一直使用的是智能指针,别的方式在网上也见过好几次,但是不明白其原理,所以也只是看看,现在想系统的学一下 COM原理,将原来大致浏览的内容重新看了...
  • dasgk
  • dasgk
  • 2013-07-05 09:38:47
  • 1737

C#创建com组件

本文详细阐述如何用C#创建COM组件,并能用VC6.0等调用。并附有完整测试通过的代码。废话不多说,下面开始介绍: 开发工具:VS2010 VS2010命令提示符在:开始-所有程序-Visual ...
  • u011776918
  • u011776918
  • 2013-12-07 10:48:53
  • 2836
收藏助手
不良信息举报
您举报文章:用C#创建COM对象
举报原因:
原因补充:

(最多只允许输入30个字)