欢迎来到老马的领地~ 这是“压风式散热底座”发明者的个人网站:) 本人QQ:80524554,用户群1:562279766
折腾了一晚,中途看火影浪费了点时间
说正事~~
并不复杂,但有些小细节需要注意,以下是流程:
一,用C#的类型库工程来生成DLL,并设置工程的属性为"COM可见":
另外,为了本机方便调试,可以把自动注册的选项勾上,相当于VB6里编译DLL时默认注册:
二,代码里面要编写一个接口,以及这个接口的实现类,并且接口与类都要设置为COM可见:
示例里是封装了.NET中RSA算法,并且解决了RSA不可处理大于128字节内容的问题(采用分段加解密方式处理,代码搬自一名台湾朋友的文章(貌似他也是MSMVP): 点击访问原文 )
其中那个数组的ref问题折腾了我一会儿,之前没加的时候VB6里报错,说是不支持的自动化类型,后来想想可能是引用传递的原因,于是加上ref,果然就OK了
三,发布问题.
发布的时候要注意,由于DLL本身是基于.Net Framework的,因此目标机器上必须得要有对应版本的Framework,此为注意点1.
注意点2,则是注册DLL的命令不再是Regsvr32,因为此DLL并非标准的COM DLL,要使用.Net中的工具去注册,如下:
regasm RSALibary.dll /tlb: RSALibary.tlb /codebase
此命令我已经写在了源码中的reg.bat中.
以上一,二两步完成,则C#的DLL工程可以编译了.
第三步即可在目标机器上发布.
编译完成后,如果在第一步里勾选了"自动注册",则会在DLL同目录下生成一个TLB文件,同时会在系统中注册.这个就是VB6中要引用的,DLL本身不能直接引用.
假如没有勾选,那每次编译后,需要自己手工运行一下reg.bat,对于开发机来说,不方便.
至于在VB6中如何使用此DLL中的类,那就与平常的COM对象一样了,就不写了,代码反正已经上传,自己看吧....
压缩包里的C#项目是VS2010版本的,所使用的.Net Framework是2.0版本的.
点击下载

说正事~~
并不复杂,但有些小细节需要注意,以下是流程:
一,用C#的类型库工程来生成DLL,并设置工程的属性为"COM可见":
另外,为了本机方便调试,可以把自动注册的选项勾上,相当于VB6里编译DLL时默认注册:
二,代码里面要编写一个接口,以及这个接口的实现类,并且接口与类都要设置为COM可见:
[ComVisible(true)] //决定是否COM可见
public interface iRSALibary
{
string RSAGetPubKey();
string RSAGetPriKey();
byte[] RSAEncode(ref byte[] plainBytes, string sPubKey); //对于数组作为参数,一定要加ref,否则VB6中不支持.
byte[] RSADecode(ref byte[] plainBytes, string sPriKey);
}
[ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)] //COM可见,以及接口类型,VB6要调用,必须使用AutoDual
public class cRSA : iRSALibary
{
private RSACryptoServiceProvider rsa;
public cRSA()
{
rsa = new RSACryptoServiceProvider();
}
public string RSAGetPubKey()
{
return rsa.ToXmlString(false);
}
public string RSAGetPriKey()
{
return rsa.ToXmlString(true);
}
public byte[] RSAEncode(ref byte[] plainBytes, string sPubKey)
{
if (plainBytes == null || plainBytes.Length <= 0)
{
throw new NotSupportedException();
}
rsa.FromXmlString(sPubKey);
int bufferSize = (rsa.KeySize / 8) - 11;
byte[] buffer = new byte[bufferSize];
using (MemoryStream input = new MemoryStream(plainBytes))
using (MemoryStream ouput = new MemoryStream())
{
while (true)
{
int readLine = input.Read(buffer, 0, bufferSize);
if (readLine <= 0)
{
break;
}
byte[] temp = new byte[readLine];
Array.Copy(buffer, 0, temp, 0, readLine);
byte[] encrypt = rsa.Encrypt(temp, false);
ouput.Write(encrypt, 0, encrypt.Length);
}
return ouput.ToArray();
}
}
public byte[] RSADecode(ref byte[] plainBytes, string sPriKey)
{
if (plainBytes == null || plainBytes.Length <= 0)
{
throw new NotSupportedException();
}
rsa.FromXmlString(sPriKey);
int keySize = rsa.KeySize / 8; byte[] buffer = new byte[keySize];
using (MemoryStream input = new MemoryStream(plainBytes))
using (MemoryStream output = new MemoryStream())
{
while (true)
{
int readLine = input.Read(buffer, 0, keySize);
if (readLine <= 0)
{
break;
}
byte[] temp = new byte[readLine];
Array.Copy(buffer, 0, temp, 0, readLine);
byte[] decrypt = rsa.Decrypt(temp, false);
output.Write(decrypt, 0, decrypt.Length);
}
return output.ToArray();
}
}
}
public interface iRSALibary
{
string RSAGetPubKey();
string RSAGetPriKey();
byte[] RSAEncode(ref byte[] plainBytes, string sPubKey); //对于数组作为参数,一定要加ref,否则VB6中不支持.
byte[] RSADecode(ref byte[] plainBytes, string sPriKey);
}
[ComVisible(true), ClassInterface(ClassInterfaceType.AutoDual)] //COM可见,以及接口类型,VB6要调用,必须使用AutoDual
public class cRSA : iRSALibary
{
private RSACryptoServiceProvider rsa;
public cRSA()
{
rsa = new RSACryptoServiceProvider();
}
public string RSAGetPubKey()
{
return rsa.ToXmlString(false);
}
public string RSAGetPriKey()
{
return rsa.ToXmlString(true);
}
public byte[] RSAEncode(ref byte[] plainBytes, string sPubKey)
{
if (plainBytes == null || plainBytes.Length <= 0)
{
throw new NotSupportedException();
}
rsa.FromXmlString(sPubKey);
int bufferSize = (rsa.KeySize / 8) - 11;
byte[] buffer = new byte[bufferSize];
using (MemoryStream input = new MemoryStream(plainBytes))
using (MemoryStream ouput = new MemoryStream())
{
while (true)
{
int readLine = input.Read(buffer, 0, bufferSize);
if (readLine <= 0)
{
break;
}
byte[] temp = new byte[readLine];
Array.Copy(buffer, 0, temp, 0, readLine);
byte[] encrypt = rsa.Encrypt(temp, false);
ouput.Write(encrypt, 0, encrypt.Length);
}
return ouput.ToArray();
}
}
public byte[] RSADecode(ref byte[] plainBytes, string sPriKey)
{
if (plainBytes == null || plainBytes.Length <= 0)
{
throw new NotSupportedException();
}
rsa.FromXmlString(sPriKey);
int keySize = rsa.KeySize / 8; byte[] buffer = new byte[keySize];
using (MemoryStream input = new MemoryStream(plainBytes))
using (MemoryStream output = new MemoryStream())
{
while (true)
{
int readLine = input.Read(buffer, 0, keySize);
if (readLine <= 0)
{
break;
}
byte[] temp = new byte[readLine];
Array.Copy(buffer, 0, temp, 0, readLine);
byte[] decrypt = rsa.Decrypt(temp, false);
output.Write(decrypt, 0, decrypt.Length);
}
return output.ToArray();
}
}
}
示例里是封装了.NET中RSA算法,并且解决了RSA不可处理大于128字节内容的问题(采用分段加解密方式处理,代码搬自一名台湾朋友的文章(貌似他也是MSMVP): 点击访问原文 )
其中那个数组的ref问题折腾了我一会儿,之前没加的时候VB6里报错,说是不支持的自动化类型,后来想想可能是引用传递的原因,于是加上ref,果然就OK了

三,发布问题.
发布的时候要注意,由于DLL本身是基于.Net Framework的,因此目标机器上必须得要有对应版本的Framework,此为注意点1.
注意点2,则是注册DLL的命令不再是Regsvr32,因为此DLL并非标准的COM DLL,要使用.Net中的工具去注册,如下:
regasm RSALibary.dll /tlb: RSALibary.tlb /codebase
此命令我已经写在了源码中的reg.bat中.
以上一,二两步完成,则C#的DLL工程可以编译了.
第三步即可在目标机器上发布.
编译完成后,如果在第一步里勾选了"自动注册",则会在DLL同目录下生成一个TLB文件,同时会在系统中注册.这个就是VB6中要引用的,DLL本身不能直接引用.
假如没有勾选,那每次编译后,需要自己手工运行一下reg.bat,对于开发机来说,不方便.
至于在VB6中如何使用此DLL中的类,那就与平常的COM对象一样了,就不写了,代码反正已经上传,自己看吧....
压缩包里的C#项目是VS2010版本的,所使用的.Net Framework是2.0版本的.
点击下载
添加评论
GB2312 https://www.m5home.com/blog/trackback.php?id=94&encode=gb2312
UTF-8 https://www.m5home.com/blog/trackback.php?id=94&encode=utf-8
这不是懒嘛.........想着C#里有现成的,结果实际上折腾更多......