用C#创建COM对象

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情
在本篇文章中,我们将讨论下面的问题:
·使用C#创建一个简单的COM对象(使用COM的Interop特性)。
·从VC++客户端软件中访问COM。客户端软件使用了TypeLibrary(.TLB文件)。
为了简单和方便开发人员使用、测试起见,我们使用了SQLSERVER数据库软件的缺省安装中的Northwind数据库。
·修改COM对象中SQLServer的名字,与SQLServer连接。
·我们已经创建了连接数据库用的分别为scott、tiger的用户名和口令,我们可以使用它或者其他现有的用户名和口令。
第一部分:用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# 使用“CoCreateInstance”函数创建一个COM对象 在正常情况下我们在C#中需要创建一个COM对象通常会选择 Activator::CreateInstance 实现 object ppvObject = Activator.CreateInstance(Type.GetTypeFromCLSID(CLSID_InternetExplorer)); 不过我们也可以选择另外几种方法 不过在这里我只提供一种较为常规的方法。 WINAPI CoCr 阅读详情

相关推荐

C#_COM组件注册与调用

安装了VS(我用的vs2012 64位) gacutil.exe路径 C:\Program Files (x86)\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools regasm.exe路径 C:\Windows\Microsoft.NET\Framework64\v4.0.30319 单独建立一个文件夹放入dll,tlb文件 将以上路径配置到电脑环境变量PATH即可在管理员权限下的控制台输入一下命令 1、cd /d dll路径 然后回车,显示dll所在文件夹路径 2、gacutil /i dll文件名.dll 然后回车,显示将dll添加进程序集成功 3、regasm dll文件名.dll /tlb:dll文件名.tlb 然后回车,显示注册成功

C#程序设计通过Attribute特定创建COM实例对象

本文讲解C#程序设计通过Attribute特定创建COM实例对象。 操作流程 1.1. 声明代码 下面声明的JetEngineClass类只有一个单单的类声明,但是没有一个成员声明,但是和一般的类声明有些不一样的是这个类多了两个特性(Attribute),把这个类和COM对象联系在一起的就是这两个特性了,其中一个是ComImportAttribute,这个特性指明了所作用的类是从COM对象中来的,GuidAttribute指明了COM对象的GUID,也就是说明了创建这个COM需用到的GUID。有了这两个特

weixin_41883890的博客 282

C#创建 COM 对象 (把 C# 类公布到 COM )

所谓在 c#创建 com 对象,实际上就是向 com 公开用 c# 编写的组件对象接口。这个 c# 类及其成员必须遵循下列规则才能对 com 可见:1> 类必须是公共的。 2> 属性、方法和事件必须是公共的。 3> 属性和方法必须在类接口上声明。 4> 事件必须在事件接口中声明。 其他没有在这些接口中声明的类的公共成员对于 com 是不可见的,但它们对于其他 .net framewor

大鸾翔宇,遨游苍穹! 1614

COM对象创建过程详细分析

1、   CoGetClassObject 函数原型: HRESULT CoGetClassObject(const CLSID& clsid, DWORD dwClsContext, COSERVERINFO* pServerInfo, const IID& iid, (void **)ppv); 参数说明:          clsid: 指定COM类厂的CLSID标识符;     

xiangzhang321的专栏 1308

C#创建COM对象[转]

在本篇文章中,我们将讨论下面的问题:   ·使用C#创建一个简单的COM对象(使用COMInterop特性)。   ·从VC++客户端软件中访问COM。客户端软件使用了TypeLibrary(.TLB文件)。   为了简单和方便开发人员使用、测试起见,我们使用了SQLSERVER数据库软件的缺省安装中的Northwind数据库。   ·修改COM对象SQLServer的名字,与SQLServe

BigMonster's Blog 929

C#创建 COM 对象

<br />所谓在 C#创建 COM 对象,实际上就是向 COM 公开用 C# 编写的组件对象接口。这个 C# 类及其成员必须遵循下列规则才能对 COM 可见:<br />1> 类必须是公共的。 <br />2> 属性、方法和事件必须是公共的。 <br />3> 属性和方法必须在类接口上声明。 <br />4> 事件必须在事件接口中声明。 <br />其他没有在这些接口中声明的类的公共成员对于 COM 是不可见的,但它们对于其他 .net Framework 对象将是可见的。<br />若要向 COM

wewaa的专栏 2051

C#创建COM对象的方法

C#做WinForm程序,时间长了难免会遇到和COM组件打交道的地方,用什么方式创建C# COM对象也成了我们必须面对的一个问题.据我所知道的创建C# COM对象的方法一共有以下几种: 1.使用.NET包装COM组件 这是最简单的就是导入COM组件所在的DLL,让IDE生成。NET一个IL包装加到项目中,这样原来COM里面所有实现了IDispatch,Dual的COM类型及其相关类型...

weixin_30672295的博客 414
上一篇: C#语言系列讲座(12) 数组
下一篇: C#语言系列讲座(13)-字符串
Ninth
博客等级 码龄22年 4粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值