COM组件和调用

1、引言

实验内容:构建一个com组件,该组件存储了10000个12位的验证码;输入一个验证码,组件返回该验证码是否正确(是否是10000个其中之一);输入一个字符串,返回一个对应的映射的验证码(映射方法自己定义);

2、实验环境

  • 操作系统:Windows 10
  • 实验工具:IntelliJ IDEA && vs2015
  • 环境:Java jdk 1.8

3、COM组件介绍

  • COM不是一种语言,而是一种标准、规范,包括一套标准API、一个标准的接口集以及COM用于支持分布式计算的网络协议。
  • COM是软件组件互相通信的一种方式,它是一种二进制和网络标准,允许任意两个组件互相通信,而不管它们在什么计算机上运行(只要计算机是相连的),不管计算机运行的什么操作系统(只要该操作系统支持COM),也不管该组件机是用什么语言编写的。
  • COM组件是遵循COM规范编写、以Win32动态链接库(DLL)或可执行文件(EXE)形式发布的可执行二进制代码,能够满足对组件架构的所有需求。遵循COM的规范标准,组件与应用、组件与组件之间可以互操作,极其方便地建立可伸缩的应用系统。
  • COM是一种技术标准,其商业品牌则称为ActiveX。ActiveX是Microsoft遵循COM/DCOM规范而开发的用于Internet的一种对象连接与嵌入技术(OLE)。ActiveX是从复合文档技术OLE成长以来的。OLE最初发布的版本只是瞄准符合文档,但在OLE2中引入了
    COM。一般常用的COM组件有两类:ActiveX DLL和ActiveX 控件 。

4、实验过程

4.1 利用C#创建一个COM组件

4.1.1 项目创建

用vs创建一个类库(.net framework),如下图所示:
figure-1

4.1.2 配置项目属性

右键项目选择项目属性,选择“应用程序”——“程序集信息”:
figure-2
勾选“使程序集COM可见”;
figure-3
点击“生成”,勾选“为COM互操作注册”;
figure-4
点击"签名",勾选为程序集签名,并新建,在新建的窗口中输入密钥名,并取消勾选“使用密码保护密钥文件”;
figure-5

4.1.3 编码实现COM组件功能

其中验证码映射规则为,输入的字符串为6位,和验证码的前六位相同即映射成功;
其中Init()方法中返回了随机生成的验证码中的一个,方便后续验证。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;

namespace ComToPython
{

    [Guid("15EE3DA3-C1E2-4D60-8FAA-CFCEDFAD0F07")]
    public interface IMyClass
    {
        string Init();
        bool VerifyCode(string input);
        string CodeMapping(string input);
    }

    [ClassInterface(ClassInterfaceType.None)]
    [Guid("214A249F-C0FE-4E71-A3F2-BB60AB8734CA")]
    [ProgId("ComToPython.Application")]
    public class ComToPython:IMyClass
    {
        string[] codes = new string[10005];
        public string Init()
        {
            //验证码字符
            char[] ch = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K','L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i','j', 'k','l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};
            Random random = new Random();
            for(int i=0;i<10000;i++)
            {
                codes[i] = "";
                for (int j = 0; j < 12; j++)
                {
                    int position=random.Next()%62;
                    codes[i] += ch[position];
                }
            }
            return codes[0];
        }
        public bool VerifyCode(string input)
        {
            for (int i = 0; i < 10000; i++)
                if (input == codes[i])
                    return true;
            return false;
        }
        public string CodeMapping(string input)
        {
            string pattern = @"^[A-Za-z0-9]+$";
            Regex regex = new Regex(pattern);
            if (input.Length != 6)
                return "字符串长度必须为6!";

            if (!regex.IsMatch(input))
                return "字符串必须由数字和字母组成!";
            
            for (int i = 0; i < 10000; i++)
                if (codes[i].Substring(0, 6) == input)
                    return "成功匹配验证码:" + codes[i];
            return "未能匹配到验证码!";
        }
    }
}

4.1.4 新建两个Guid

新建两个Guid,并复制替换代码中的Guid;
figure-6
选择新建GUID,然后复制替换代码中的GUID;
figure-7

4.1.5 生成解决方案

figure-8
到该Visual studio工程下的bin-Debug路径下可以看到生成的文件;
figure-9

4.2 使用JAVA调用COM组件

4.2.1 注册COM组件至系统

运行visual studio开发人员命令符,需要用管理员身份运行,否则会注册失败;
figure-10
cd到ComToJava.dll所在的路径下(即Visual studio工程下的bin-Debug下);
(1)执行:gacutil /i ComToJava.dll 添加dll至全局缓存;
(2)执行:regasm ComToJava.dll 注册dll至系统;
figure-11
运行regedit查看注册表,若在目录HKEY_CLASSES_ROOT下可以找到ComToJava.Application则表示已经注册;
figure-12
将附件jacob-1.19文件夹里的jacob-1.19-x64.dll放到目录C:\Windows\System32下;
将附件jacob-1.19文件夹里的jacob-1.19-x86.dll放到目录C:\Windows\SysWOW64下;

4.2.2 新建java项目,并导入jacob.jar

右键项目,选择“Open Module Settings”;
figure-13
左侧选择Modules,选择“Dependencies”,然后右侧点击加号,选择第一项;
figure-14
找到jacob.jar所在的位置,并添加;
figure-15

4.2.3 编写java调用代码并运行

代码如下:

package com.comtojava;
import com.jacob.activeX.ActiveXComponent;    
import com.jacob.com.ComThread;    
import com.jacob.com.Dispatch;    
import com.jacob.com.Variant;

import java.util.Scanner;

public class test {    
  
    /**    
     * @param args    
     */    
    public static void main(String[] args) {    
        // TODO Auto-generated method stub
        try{    
            ActiveXComponent dotnetCom = null;    
            dotnetCom = new ActiveXComponent("ComToPython.Application");
            Variant var = Dispatch.call(dotnetCom,"Init");
            System.out.println("验证码示例如下:");
            System.out.println(var.toString());
            System.out.println();

            System.out.println("请选择操作:1:输入验证码判断是否正确");
            System.out.println("1:输入验证码判断是否正确");
            System.out.println("2:输入字符串返回对应的验证码");
            System.out.println("输入0退出!");
            int choice;
            Scanner scanner=new Scanner(System.in);
            choice=scanner.nextInt();
            while(choice!=0)
            {
                switch (choice)
                {
                    case 1:
                        System.out.println("请输入验证码:");
                        String testCode=scanner.next();
                        var = Dispatch.call(dotnetCom,"VerifyCode",testCode);
                        if(var.getBoolean())
                            System.out.println("该验证码正确!");
                        else
                            System.out.println("该验证码错误!");
                        break;
                    case 2:
                        System.out.println("请输入6位由数字和字母(大小写均可)组成的字符串:");
                        String code=scanner.next();
                        var = Dispatch.call(dotnetCom,"CodeMapping",code);
                        System.out.println(var.toString());
                }
                System.out.println();
                System.out.println("请选择操作:");

                choice=scanner.nextInt();
            }
            } catch (Exception ex) {    
                ex.printStackTrace();    
            }    
    }      
}

运行结果如下:
figure-16
figure-17

5、遇到的问题及解决方案

1、利用c#生成解决方案时,无权限,需要以管理员身份运行项目再进行生成即可;
2、利用c#生成解决方案时,本机是不能使用x64,否则会出现不能注册组件的问题;
3、java调用COM组件时,报错如下:
figure-18
原因时相关服务没有开启,打开任务管理器,开启如下服务即可成功;
figure-19

  • 2
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值