从COM组件调用.NET组件编程实战

原创 2004年01月16日 10:11:00

作者:朱学武

 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />

在我的编程实践中,需要从.NETWeb Form页面传递加密的字符串信息(如用户名和密码等)ASP页面,然后在该页面对该加密字符串进行解密。如果传递的不是加密串,通过GETPOST的方式就可以直接传递并在ASP页面中接收,但问题是在.NETWeb Form页面中加了密的字符串如何才能在ASP中进行解密呢?这主要由于ASP并不能直接访问由.NET提供的托管类和组件。这时我们就只能借助于COM组件来实现了,通过COM的互操作我们可通过.NET生成COM组件,然后在ASP页面中访问该COM组件就可以了。

      

       本文实现的是将加密的用户名与密码从.aspx页面传递到.asp页面,下面就来介绍这些操作的具体步骤:

      

一、制作具有加密、解密字符串的.NET程序集(VS.NET类库工程)

这个程序集将会变成COM组件,使用DES对称加密代码,可以加密码,可以加密解密,支持中文!

//文件名:StringCrypt.cs

using System;

using System.Runtime.InteropServices;

using System.Security.Cryptography;

using System.IO;

using System.Text;

 

namespace jonson

{

       // 首先建立接口,这个是Com必须使用的

[Guid("BF6F9C17-37FA-4ad9-9601-C11AD5316F2C")]

       public interface IEncrypt

       {

              string Encrypt(string pToEncrypt,string sKey);

              string Decrypt(string pToDecrypt,string sKey);

       }

 

       //接口的实现

       [Guid("3FBDBB63-3C36-4602-89E1-73EDB0F167D0")]

       public class StringCrypt : IEncrypt

       {

              // 加密的方法

public string Encrypt(string pToEncrypt, string sKey) 

              { 

                     DESCryptoServiceProvider des = new DESCryptoServiceProvider(); 

                     //把字符串放到byte数组中 

                     byte[]  inputByteArray  =  Encoding.Default.GetBytes(pToEncrypt); 

                     //byte[]  inputByteArray=Encoding.Unicode.GetBytes(pToEncrypt); 

 

                     //建立加密对象的密钥和偏移量 

                     //原文使用ASCIIEncoding.ASCII方法的GetBytes方法 

                     //使得输入密码必须输入英文文本 

                     des.Key  =  ASCIIEncoding.ASCII.GetBytes(sKey); 

                     des.IV  =  ASCIIEncoding.ASCII.GetBytes(sKey); 

                     MemoryStream  ms  =  new  MemoryStream(); 

                     CryptoStream  cs  =  new  CryptoStream(ms,  des.CreateEncryptor(),CryptoStreamMode.Write); 

                     //Write  the  byte  array  into  the  crypto  stream 

                     //(It  will  end  up  in  the  memory  stream) 

                     cs.Write(inputByteArray,  0,  inputByteArray.Length); 

                     cs.FlushFinalBlock(); 

                     //Get  the  data  back  from  the  memory  stream,  and  into  a  string 

                     StringBuilder  ret  =  new  StringBuilder(); 

                     foreach(byte  b  in  ms.ToArray()) 

                     { 

                            //Format  as  hex 

                            ret.AppendFormat("{0:X2}", b); 

                     } 

                     ret.ToString(); 

                     return  ret.ToString(); 

              }

             

              // 解密的方法

              public string  Decrypt(string pToDecrypt,  string sKey) 

              { 

                     DESCryptoServiceProvider des = new DESCryptoServiceProvider(); 

 

                     //Put  the  input  string  into  the  byte  array 

                     byte[]  inputByteArray = new byte[pToDecrypt.Length / 2]; 

                     for(int x = 0; x < pToDecrypt.Length / 2;  x++) 

                     { 

                            int i = (Convert.ToInt32(pToDecrypt.Substring(x * 2, 2), 16)); 

                            inputByteArray[x] = (byte)i; 

                     } 

 

                     //建立加密对象的密钥和偏移量,此值重要,不能修改 

                     des.Key = ASCIIEncoding.ASCII.GetBytes(sKey); 

                     des.IV = ASCIIEncoding.ASCII.GetBytes(sKey); 

                     MemoryStream ms = new MemoryStream(); 

                     CryptoStream cs = new CryptoStream(ms, des.CreateDecryptor(), CryptoStreamMode.Write);

                     //Flush the data through the crypto stream into the memory stream 

                     cs.Write(inputByteArray, 0, inputByteArray.Length); 

                     cs.FlushFinalBlock(); 

 

                     //Get the decrypted data back from the memory stream 

                     //建立StringBuilder对象,CreateDecrypt使用的是流对象,必须把解密后的文本变成流对象 

                     StringBuilder ret = new StringBuilder(); 

            

                     return System.Text.Encoding.Default.GetString(ms.ToArray()); 

              }

       }

}

说明:注意上面的Guid是使用vs.net工具菜单里面的创建guid工具生成的,这个每个Com组件所必须的。输入密匙的时候,必须使用英文字符,区分大小写,且字符数量是8个,不能多也不能少,否则出错。  

 

然后使用vs.net的“Vsitual Studio .Net工具”-->Vistual Studio .Net命令提示符。在命令行内打下cd c:/ <回车>

sn -k myKey.snk<回车>

这样就在C盘根目录下生成一个名叫myKey.snk的强名称文件,然后将其拷贝到上述工程目录中(与StringCrypt.cs文件同目录)后关闭提示符窗口。

vs.net的那个类库工程自动生成的AssemblyInfo.cs文件内

[assembly: AssemblyKeyFile("")]改成[assembly: AssemblyKeyFile("../../myKey.snk ")]

[assembly: AssemblyVersion("1.0.*")]改成[assembly: AssemblyVersion("1.0.0.0")] // 注意:这时你的Com组件版本为1.0.0.0

 

然后按Shift + Ctrl + B键生成dll库(使用Release模式),StringCrypt.dll。这时候,程序集就建立成功了。

 

二、注册该程序集并创建一个类型库

 

仍然使用开始菜单中的Visual Studio .Net命令提示符

进入你的项目目录,假设为D:/project/bin/Release

在对话框中输入

d:<回车>

cd project/bin/release<回车>

然后输入 dir 命令可以看见StringCrypt.dll文件

然后输入:regasm StringCrypt.dll<回车>

然后就在这个目录下生成了StringCrypt.tlb类型库文件。不要关闭此提示符窗口。

这时候,这个.dll.net程序集就变成一个标准的Com组件了,但是还不能用,必须让它变成全局Com组件。

 

这个regasm 实用程序将创建一个类型库并在 Windows 注册表中对其进行注册,以便 COM Services可以访问.NET组件。在使用regasm.NET进行注册之后,标准的Windows客户就可以后期绑定组件中的类。注册组件的过程必须一次完成。在.NET组件被注册之后,所有的COM 客户都可以访问它。

 

三、将程序集添加到全局程序集缓存中

 

在使用.NET程序集之前,我们必须把程序集安装到全局的高速缓存中。为此进入Visual Studio .Net提示符窗口,输入

 

gacutil /I StringCrypt.dll<回车>

 

这时,你的这个dll就被复制到全局程序集缓存中了。也就是说无论在这个电脑的哪个硬盘上都可以使用此dll组件了。

 

四、使用方法

1. source.aspx中生成加密串

using jonson;

jonson.StringCrypt crypt = new jonson.StringCrypt();

String tmpstr =  username+"^"+password;

… …

strinfo = crypt.Encrypt(tmpstr,"fk58Fgju"); // fk58Fgju为密匙

Response.Redirect("target.asp?info="+strinfo);

 

2. target.asp页面中接收并解密字符串

info = Request.QueryString(“info”)

set obj = Server.CreateObject("jonson.StringCrypt")

 

str1 = obj.Encrypt(info,"fk58Fgju") // 解密

 

本文的顺利实现,得到了网友TomMax(笑望人生)等人的大力帮助,在此表示衷心的感谢。

IIS调用COM组件的权限问题

情形1 问题描述 C#.NET编写了一个webservice的接口,供公司的的其他地方发送和接收短信(采用的方式是:再服务器上安装...
  • BleuRever
  • BleuRever
  • 2016年03月02日 21:15
  • 3508

C#创建COM组件,并在ASP、PHP中调用方法

1、新建项目        -- 选择Visual C# - 类库        -- 项目名称:如 SendMailLib        -- 去掉选中项 ”为解决方案创建目录”        --...
  • xmlife
  • xmlife
  • 2016年06月11日 10:44
  • 1155

ASP.NET调用COM

在VC++z中利用ATL COM AppWizard写一个COM组件。   在VS.NET中利用“型别库导入工具”(TlbImp.exe),从COM组件的型别库生成一个装配件,这样受控代码就能通过访问...
  • tohigh
  • tohigh
  • 2004年06月26日 14:37
  • 4586

从COM组件调用.NET组件编程实战

在我的编程实践中,需要从.NET的Web Form页面传递加密的字符串信息(如用户名和密码等)到ASP页面,然后在该页面对该加密字符串进行解密。如果传递的不是加密串,通过GET或POST的方式就可以直...
  • qudymeteor
  • qudymeteor
  • 2007年10月18日 15:43
  • 439

.NET调用Com组件事例

在程序设计中,往往通过键盘的某个按键来完成相关操作!  下面就来说明如何实现: 1.引入名称空间;using System.Runtime.InteropServices;(由于使用到API(user...
  • shizhiyingnj
  • shizhiyingnj
  • 2007年02月11日 23:23
  • 7261

NET组件和COM组件之间的相互操作

NET组件和COM组件之间的相互操作 .NET组件和COM组件之间的相互操作日期:2001-10-18 19:29:00出处:技术巅峰 作者:技术巅峰...
  • aiwtu
  • aiwtu
  • 2006年11月22日 11:15
  • 1293

如何创建COM组件能够调用的.NET装配件

前言:    .NET中的代码是不能够直接被COM组件使用的,为了能够在COM组件中使用.NET的代码生成的组件,我们需要创建一个相当于代理的中间介质,它叫做可调用COM包装器(COM callabl...
  • storm97
  • storm97
  • 2003年09月24日 20:31
  • 1239

从COM组件调用.NET 组件

互操作性的优势有时,编程中的革新会使人不得不放弃以前的所有工作。举一个很极端的例子,假设您已有多年 Visual Basic 编程经验,象许多开发人员一样,您当时已建立起一个颇具规模的代码库,而且,由...
  • guxianga
  • guxianga
  • 2007年09月18日 13:11
  • 1274

NET中如何引用COM组件

如果您是初次学习.NET,说不定会尝试着去学习怎样使用COM组件,为了让您少走弯路,我把我所遇到的问题写下来,与大家共享。同时也希望与您一起交流,共同提高。联系方式:电话:0571-88021712 ...
  • lvboliang
  • lvboliang
  • 2007年06月05日 21:15
  • 1232

C#开发COM组件供其他开发环境或工具调用介绍

由于工作原因涉及到这一块的开发,由于之前并未接触过,所以本篇文章也是在参考了各种资料后,自己实现并通过通过测试之后所整理的备忘录以及一些个人观点。 希望对刚接触这类型开发的朋友有所帮助,若有不足...
  • xiunai78
  • xiunai78
  • 2013年09月10日 11:23
  • 6249
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:从COM组件调用.NET组件编程实战
举报原因:
原因补充:

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