VS2013编写ATL简单对象在PHP中使用

我们用文件读写来模拟

先用VS2013新建一个Visual C++语言的ATL-〉ATL项目


给网页用的COM对象,相当于进程内服务器,所以应用类型为DLL,勾上“允许合并代理/存根代码”,对网页用COM对象,避免分开编译代理和存根更方便


在项目中“添加类”,选择类型为:ATL简单对象


给ATL简单对象(一个COM类)进行命名,我们添加简称FileKey,其余自动生成的。注意需要自己添加ProgID(一般命名成:DLL文件名(即工程名).COM类名(即简称))


指定COM对象的一些特性:如线程安全模型用 套间(Apartment,即图中的“单元”),支持“聚合”,双重接口,支持错误信息、连接点、IE对象支持等


因为我们通过COM对象暴露的接口来调用其中的方法、属性,所以,右键选中接口IFileKey,打开“添加方法”的向导

VS2013编写ATL简单对象在PHP中使用_第1张图片

指定方法名GetContent,添加第一个输入性LONG类型参数lFlags


添加第二个输出返回性BSTR*类型的参数pFileContent,注意,[out,retval]参数相当于我们方法被调用时的返回值,BSTR*作为输出性的字符串参数的类型


添加GetContent方法的具体内容:创建文件ttt.txt,可读可写,读取该文件的内容,在该内容后面添加一点后返回给pFileContent,然后写入添加后的内容到文件。注意:如果文件路径为ttt.txt,在Windows 7上,该文件创建在桌面,如果改成.\\ttt.txt,我的情况它生成在apache的安装目录的根下(可能默认文件的读写者就是apache这样的Web服务器)


给我们的FileKey添加安全相关内容:让COM类从IObjectSafetyImpl接口(模板接口)继承,并在接口入口映射中添加IObjectSafety

编译生成DLL,将该DLL放到一定地方(我放到了文档根www),用regsvr32.exe /i  UseFileTestATL.dll进行控件的注册,可以在注册表检查FileKey的注册情况,注意ProgID

编写测试用的php文件testcom.php如下:

    $obj = new COM("UseFileTestATL.FileKey");
    $str = $obj->GetContent(12);
   
    echo $str;

?>

然后输入http://127.0.0.1/testcom.php测试,可以发现不断增长的“在tick=77881330添加值12 在tick=77883795添加值12 在tick=77891377添加值12 ……”

在上述测试中,COM对象是在服务器上测试,php中调用的,这种方式适合在服务端(Windows环境)打开php和COM对象之间的联系,可以用于扩展php难以支持的功能

另外,我们在new COM中使用了ProgID作为参数,但COM对象不一定有ProgID。查看php中COM类的官网说明:

module_name

Can be a ProgID, Class ID or Moniker that names the component to load

意思是这个参数除了可以是ProgID外,也可以是COM类的UUID或者Moniker命名对象,后两者未试,但一个COM类肯定有UUID的

要让COM对象工作在客户端,必须要让客户可以下载该对象并进行注册(通常打包成cab),然后在网页进行调用。

查看FileKey.rgs了解UUID:

VS2013编写ATL简单对象在PHP中使用_第2张图片

编写inf文件UseFileTestATL.inf:

[version]
signature="$CHICAGO$"
AdvancedINF=2.0

[Add.Code]
UseFileTestATL.dll=UseFileTestATL.dll

[UseFileTestATL.dll]
file-win32-x86=thiscab  
RegisterServer=yes
clsid={F595E720-32BC-4AAC-AA58-806F6359AFF9}
DestDir=11  
FileVersion=1,0,0,1

[RegisterFiles]
%11%\UseFileTestATL.dll

打开VS2013 x86本机工具命令提示,输入iexpress运行打包cab的工具程序。(这个程序似乎装了VS就被安装到了系统目录下)

选择“Create new Self Extraction Directive file”,选择“Create compressed files only(ActiveX Installs)”,点Add,添加进去UseFileTestATL.dll和UseFileTestATL.inf这两个文件,输入(或浏览再输入)cab文件存放的位置(提示要求输入8.3格式的cab文件名),如V:\UFTATL.cab,再勾上“Store files using Long File Name inside Package”(即cab内文件名可以用长文件名),SED可以不保存。最后生成cab。如果出现Unable to Open Report File这样的错误,是权限问题,用管理员身份重新运行iexpress即可。

编写testcom.htm如下:

--------------------------------




   
 网页测试ATL简单对象



    js调用ActiveX




------------------------------------

在浏览器输入http://127.0.0.1/testcom.htm,将出现如下提示:


这是浏览器为了安全考虑,将未签名的控件进行了拦截。选择允许,就可以试验我们的控件在网页的行为了。这种方式适合在客户端使用COM。

上面的图中,公司名等信息看上去未完善,而且每次要额外点击允许。


VS2013从浏览器对控件进行调试还是比较方便的,例如,在前面的testcom.htm中,去掉codebase部分,然后regsvr32.exe /u UseFileTestATL.dll注销控件,以管理员身份运行VS2013(不是管理员不能实现控件生成后自动注册),设置项目的属性-〉调试属性,将调试器改成Web浏览器调试器,指定url,类似如下:

 然后下断点,按F5开始调试即可。


修改控件显示的公司名、文件说明,可以在资源文件的版本信息中修改:


控件签名问题,可以参考以下网址的文章http://www.cnblogs.com/itech/archive/2011/07/21/2110924.html,概括如下:

要进行数字签名,需要以下准备:
1)数字证书和密码;  ------------------〉这个真正使用需要购买,可以创建测试用的证书和密码
2)数字签名工具;
3)时间戳服务器的URL地址;

数字签名工具:(进入VS2013开发人员命令提示以下命令均可使用)

signtool.exe 数字签名工具

makecert.exe 创建数字证书

cert2spc.exe 将数字证书转化为软件发布者证书格式

pvk2pfx.exe(pvkimprt.exe) 将私有的密匙和软件发布者证书合并为pfx文件,此文件将被signtool.exe使用

makecert -sv mykey.pvk -n "CN=Sjg Software Inc." mycert.cer
会要求密码,作为简单测试我们都输入12345678,生成pvk文件和cer文件

cert2spc mycert.cer mycert.spc

将cer转换成spc

V:\>pvk2pfx -pvk mykey.pvk -pi 12345678 -spc mycert.spc -pfx mycert.pfx -po 12345678

使用pvk、spc生成pfx


V:\>signtool sign /f mycert.pfx /p 12345678 /t http://timestamp.globalsign.com/scripts/timstamp.dll /v UFTATL.CAB

上面这句失败,无法签名

SignTool sign /fd SHA256 /a /f mycert.pfx /p 12345678 UFTATL.CAB  也无法签名

后来发现,VS中,如果是C#的项目,在项目-〉属性-〉签名(VC中没有这个页,而且显示的风格也不一样),有“创建测试证书”的按钮,可以生成pfx(可设密码),用这个生成的pfx,可以通过signtool    sign命令,给cab签名。

通过另一机器IE,先将pfx文件导入到IE的证书-〉受信任的根证书列表里,然后以Web方式访问前面的testcom.htm,会出现安装控件的提示,并且会显示签名者信息,安装后,就可以不跳出拦截提示了。(值得注意的是,真实生产环境应该用release版,而且应该将ATL相关的库dll拷贝到cab,当然,证书最好使用正式证书)

 



你可能感兴趣的:(VS2013编写ATL简单对象在PHP中使用)