把ic卡的读方法封装成activex控件给js调用

来源:互联网 发布:opencv vibe算法改进 编辑:程序博客网 时间:2024/04/28 12:57

最近刚用delphi实行了一个ic卡的读写,需要将读方法封装成activex给js调用,今天弄了一下,有几个要点记录一下。

1、automation object 中实现一个方法,只能返回HRESULT,也就是说只能实现procedure,我想用传出参数的方式来实现读出的数据,但是js里面一直提示“不支持方法和属性”的错误。后来想了个办法,在接口里面实现一个读方法,同时实现一个属性,在读方法里面将读到的值赋给属性,然后js再调用属性得到。

2、setup.inf及html里面的clsid:setup.inf中随便用,在html中的object应该用到delphi中Class***对应的guid,例如在***TLB.pas文件中:
        LIBID_hxcardactive: TGUID = '{05CC7E64-2ACA-4B74-9FDA-2F46C2A87826}';
        IID_Ihxcard: TGUID = '{03DD21A9-7B79-48CF-ABEE-A677AC4CB3B7}';
        CLASS_hxcard: TGUID = '{CFE20654-45F3-4260-B71E-219E1E6FEAA9}';
    html中应该用最后一个CFE20654-45F3-4260-B71E-219E1E6FEAA9。

3、active签名问题:由于现在的ie对安全都加强了,未签名过的activex直接就不能使用,所以在开发阶段需要实现一个本地签名环境,所以从http://files.cnblogs.com/babyt/SignTool.rar下载了一个工具,具体做法如下:
      1.)   makecert -n "CN=TempRoot" -r -sv TempRoot.pvk TempRoot.cer
      得到一个自认证证书TempRoot.cert,其密钥文件为TempRoot.pvk
      2.)    makecert -sk TempCA -iv TempRoot.pvk -n "CN=TempCA" -ic TempRoot.cer TempCA.cer -sr currentuser -ss My
      得到一个由刚才TempRoot所颁发的子证书TempCA,且被保存到"个人"证书库中
      3.)      certmgr
      打开证书管理器,可看到"个人"里已经含有TempCA,点击标签页"可信任的根证书机构",点击"导入",将TempRoot.cert导入,这样一来TempCA的证书链就是完整且可信任的了。
      4. )    signtool 根据界面提示对cab文件进行签名。(cab用iexpress生成)

4、本地文件测试之后,一般会在本地web服务器上进行测试,需要在ie中将域名加入可信列表,否则还是会出现权限问题。
5、ie上提示“控件和本页上的其它部份的交互可能不安全”的问题,需要在代码中实现IObjectSafety接口,例子如下(照样画葫芦既可):
 

type
  TUpdaterX = class(TAutoObject,IObjectSafety, IUpdaterX)
  private
    FObjectSafetyFlags: DWORD;
  protected
    procedure Start; safecall;
    { IObjectSafety }
    function GetInterfaceSafetyOptions(const IID: TIID; pdwSupportedOptions,
      pdwEnabledOptions: PDWORD): HResult; virtual; stdcall;
    function SetInterfaceSafetyOptions(const IID: TIID; dwOptionSetMask,
      dwEnabledOptions: DWORD): HResult; virtual; stdcall;
  end;

implementation

uses ComServ, Main;

function TUpdaterX.GetInterfaceSafetyOptions(const IID: TIID;
  pdwSupportedOptions, pdwEnabledOptions: PDWORD): HResult;
var
  Unk: IUnknown;
begin
  if (pdwSupportedOptions = nil) or (pdwEnabledOptions = nil) then
  begin
    Result := E_POINTER;
    Exit;
  end;
  Result := QueryInterface(IID, Unk);
  if Result = S_OK then
  begin
    pdwSupportedOptions^ := INTERFACESAFE_FOR_UNTRUSTED_CALLER or
      INTERFACESAFE_FOR_UNTRUSTED_DATA;
    pdwEnabledOptions^ := FObjectSafetyFlags and
      (INTERFACESAFE_FOR_UNTRUSTED_CALLER or INTERFACESAFE_FOR_UNTRUSTED_DATA);
  end
  else begin
    pdwSupportedOptions^ := 0;
    pdwEnabledOptions^ := 0;
  end;
end;

function TUpdaterX.SetInterfaceSafetyOptions(const IID: TIID; dwOptionSetMask,
  dwEnabledOptions: DWORD): HResult;
var
  Unk: IUnknown;
begin
  Result := QueryInterface(IID, Unk);
  if Result <> S_OK then Exit;
  FObjectSafetyFlags := dwEnabledOptions and dwOptionSetMask;
end;