C#能写COM组件吗?

lemon_wei 2005-11-28 10:53:30
新手问一下,C#能写COM组件吗,我看了一下没找到。用VC++写COM太麻烦,而且他自动生成的代码有的还有错误,很不好用。
...全文
352 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
sdenli 2006-03-06
  • 打赏
  • 举报
回复
MARK
marvelstack 2005-12-04
  • 打赏
  • 举报
回复
http://www.csdn.net/develop/Read_Article.asp?id=23438
lemon_wei 2005-12-03
  • 打赏
  • 举报
回复
多谢
ysgan 2005-11-28
  • 打赏
  • 举报
回复
up!
gabriel1 2005-11-28
  • 打赏
  • 举报
回复
good
jxufewbt 2005-11-28
  • 打赏
  • 举报
回复
简单的做法就是:

按照上面说的建个DLL工程,写个接口和具体实现类,给他们一个GUID,并签名DLL
就如--从COM组件调用.NET组件编程实战 上所说的.然后1.生成类型库;2.注册类型库;3.安装到GAC;就如--如何创建COM组件能够调用的.NET装配件上所说的.
jxufewbt 2005-11-28
  • 打赏
  • 举报
回复
#region IOLpt1 成員

public bool WriteCommand(string com,string flag)
{
//MessageBox.Show("WriteCommand方法已經運行","Error");
//com為指令碼 str為要列印字符串
ExeFunction ef = new ExeFunction();
string[] str = com.Split(new Char[]{'~'});
//開始將textBox中的外碼取出找到數組中對應的指令碼組成完整的指令
string Instruction = "";
string outI = str[0].Trim();
if(outI!="SET")
{
for(int i = 0;i<myArray.Length/5;i++)
{
if(myArray[i,0].Trim() == outI)
{
char temp1 = Convert.ToChar(Convert.ToInt32(myArray[i,1].Trim()));
char temp2='1';

Instruction = temp1.ToString();

if(myArray[i,2].Trim() != "")
{
temp2 = Convert.ToChar(Convert.ToInt32(myArray[i,2].Trim()));
Instruction += temp1.ToString();
}

if(myArray[i,3].Trim() != "")
Instruction += myArray[i,3].Trim();

Instruction += str[1] + Convert.ToChar(Convert.ToInt32(myArray[i,4].Trim()));
comlist += Instruction + "~";
if(flag == "0") //則將指令預存起來
return true;
//MessageBox.Show("方法已經運行完畢","Error");
}
}
if(comlist!="")
{
string[] str1 = comlist.Split(new Char[]{'~'});
comlist="";
for(int j=0;j<str1.Length-1;j++)
{
byte[] buffer = System.Text.Encoding.Default.GetBytes(str1[j]);
ef.StartP(buffer);
}
}
}else if(outI == "SET") //如果為SET則為設置本機收銀機
{
sqlStr = "update printTypeSet set Flag = false";
myComm = new OleDbCommand(sqlStr,myConn);
myConn.Open();
myDr = myComm.ExecuteReader();
myDr.Close();
sqlStr = "update printTypeSet set Flag = true where PrintType='" + str[1].Trim() + "'";
myComm = new OleDbCommand(sqlStr,myConn);
int i = myComm.ExecuteNonQuery();
myDr.Close();
myConn.Close();
if(i>0)
MessageBox.Show("設定成功!","OK");
else
MessageBox.Show("沒有合適的型號!","OK");
}
return true;
}

public void WhenLoad()
{
//MessageBox.Show("WhenLoad方法已經運行","Error");
int i = 0;
//先取得資料的行數
//將資料取出放入到數組裡面
try
{
sqlStr = "SELECT count(*) FROM printTypeSet WHERE Flag = true";
myComm = new OleDbCommand(sqlStr,myConn);
myConn.Open();
myDr = myComm.ExecuteReader();
if(myDr.HasRows)
{
while(myDr.Read())
{
i = (int)myDr[0];
}
}
myDr.Close();
myArray = new string[i,5];
sqlStr = "SELECT Instruction,FirstI,SecondI,Parameter,EndI FROM printTypeSet WHERE Flag = true";
myComm = new OleDbCommand(sqlStr,myConn);
myDr = myComm.ExecuteReader();
i = 0;
if(myDr.HasRows)
{
while(myDr.Read())
{
myArray[i,0] = myDr[0].ToString();
myArray[i,1] = myDr[1].ToString();
myArray[i,2] = myDr[2].ToString();
myArray[i,3] = myDr[3].ToString();
myArray[i,4] = myDr[4].ToString();
i++;
}
}
myDr.Close();
}
catch(Exception ex)
{
MessageBox.Show("WhenLoad方法運行錯誤" + ex.ToString(),"Error");
}
finally
{
myConn.Close();
//MessageBox.Show("方法已經運行完畢","Error");
}
}

#endregion

#region IObjectSafety 成員

public void GetInterfacceSafyOptions(Int32 riid, out Int32 pdwSupportedOptions, out Int32 pdwEnabledOptions)
{
// TODO: 加入 UserControl1.GetInterfacceSafyOptions 實作
pdwSupportedOptions = new Int32 ();
pdwEnabledOptions = new Int32 ();
}

public void SetInterfaceSafetyOptions(Int32 riid, Int32 dwOptionsSetMask, Int32 dwEnabledOptions)
{
// TODO: 加入 UserControl1.SetInterfaceSafetyOptions 實作
}

#endregion
}
}

jxufewbt 2005-11-28
  • 打赏
  • 举报
回复
可以,以下是转贴:

用C#寫COM組件

步驟一:
建立“windows控制項程式庫”工程,如圖: jiangligongcheng.bmp
步驟二:
在我們這個例子中用不到帶界面的com控件所以我們將界面的size屬性設置為 0, 0
我們要用C#寫COM組件必須要實現 public interface IObjectSafety接口因為這是。IObjectSafety接口,把ActiveX控件标记为安全的ActiveX控件。每個接口需要一個GUID特性。要生成變個唯一的Guid,需要運行guidgen.exe工具軟體,要選擇第四項“Registry Format” 如圖:guidgen.bmp
我們還有定義一個接口如下
[Guid("1B1DFAE7-FC2E-4f05-BC5A-5267408EF2A9")]
public interface IOLpt1
{
[DispId(1)] bool WriteCommand(string com,string flag);
[DispId(2)] void WhenLoad();
}
功能是提供一個其他語言利用我們所寫的方法的接口。如果不用接口的話其他語言將無法使用我們在程序裡面定義的方法(我在其他的地方也看到過不用接口的例子,不知道為什麼,在我的電腦上如果不用接口編譯隻後將看不到我定義的方法)。這個接口定義了兩個方法分別是 bool WriteCommand(string com,string flag); 和 void WhenLoad();
第一個方法是將命令寫入到並口,第二個方法是當控件啟動的時候讀取Access的命令的內碼並存如到數組中。這裡我們隻介紹如何寫COM組件,其他的將不涉及。
定義類 UserControl1 繼承 System.Windows.Forms.UserControl 實現接口IOLpt1於IObjectSafety

[Guid("AC8C1E64-B501-4f8b-A026-B4F1D8EF7DF2")]
[ ClassInterfaceAttribute(ClassInterfaceType.AutoDual) ]
public class UserControl1 : System.Windows.Forms.UserControl,IOLpt1,IObjectSafety
步驟三
我們還要給我們的控件一個強名。強名需要用sn.exe來得到 命令格式
sn -k myKey.snk 將得到的強名文件myKey.snk復制到你的工程的目錄下,並在我們的工程文件 AssemblyInfo.cs裡面的[assembly: AssemblyKeyFile("")]項中加入你的強名的絕對路徑F:\webpriteCon\PrintExe\mykey.snk
例如:[assembly: AssemblyKeyFile("F:\\webpriteCon\\PrintExe\\mykey.snk")]
步驟四
如圖:shuxing
將建置項裡面的「注冊COM組件Interop」項設置為true然後編譯隻後就可以注冊到其他的機器讓別的語言進行引用了。
下面是詳細代碼。
我將陸續寫出如何將COM組件發布成ActiveX控件。

using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Data.OleDb;

namespace PrintExe
{
/*必須要實現IObjectSafety接口,
* 把ActiveX控件標記為安全的ActiveX控件。
* IObjectSafety 的實現方式如下
*/
[Guid("10615515-3979-4f87-A0C9-F786F050AE8B"),InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IObjectSafety
{
// methods
[DispId(1)] void GetInterfacceSafyOptions(
System.Int32 riid,
out System.Int32 pdwSupportedOptions,
out System.Int32 pdwEnabledOptions);
[DispId(2)] void SetInterfaceSafetyOptions(
System.Int32 riid,
System.Int32 dwOptionsSetMask,
System.Int32 dwEnabledOptions);
}


[Guid("1B1DFAE7-FC2E-4f05-BC5A-5267408EF2A9")]
public interface IOLpt1
{

[DispId(1)] bool WriteCommand(string com,string flag);
[DispId(2)] void WhenLoad();
}

[Guid("AC8C1E64-B501-4f8b-A026-B4F1D8EF7DF2")]
[ ClassInterfaceAttribute(ClassInterfaceType.AutoDual) ]
public class UserControl1 : System.Windows.Forms.UserControl,IOLpt1,IObjectSafety
{
string sqlStr;
static string connStr = @"Jet OLEDB:Global Partial Bulk Ops=2;Jet OLEDB:Registry Path=;Jet OLEDB:Database Locking Mode=1;Data Source='C:\\printTypeDB.mdb';Mode=Share Deny None;Jet OLEDB:Engine Type=5;Provider='Microsoft.Jet.OLEDB.4.0';Jet OLEDB:System database=;Jet OLEDB:SFP=False;persist security info=False;Extended Properties=;Jet OLEDB:Compact Without Replica Repair=False;Jet OLEDB:Encrypt Database=False;Jet OLEDB:Create System Database=False;Jet OLEDB:Don't Copy Locale on Compact=False;User ID=Admin;Jet OLEDB:Global Bulk Transactions=1";

OleDbConnection myConn = new OleDbConnection(connStr);
OleDbCommand myComm;
OleDbDataReader myDr;
public string comlist="";
string[,] myArray;

private System.ComponentModel.Container components = null;

public UserControl1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if( components != null )
components.Dispose();
}
base.Dispose( disposing );
}

#region 元件設計工具產生的程式碼
/// <summary>
/// 此為設計工具支援所必須的方法 - 請勿使用程式碼編輯器修改
/// 這個方法的內容。
/// </summary>
private void InitializeComponent()
{
//
// UserControl1
//
this.Name = "UserControl1";
this.Size = new System.Drawing.Size(0, 0);

}
#endregion

110,534

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧