是真坑,php引用COM组件踩坑记录

这是一篇恨无聊的踩坑记录,希望能在遇到同样问题的时候给予帮助…

概述

最近工作事项中出现一项“零工”,要在已有的php工程中增加一项功能,而且工程以及所需要实现功能的源代码工程也都有,本是一件很容易的事情。虽然我鲜少用到php,不过这不是最重要的“限制因素”,让我头疼的是,功能库部分是用.NET框架实现的,里面有很多对数据格式的调整,相对比较复杂,没有功能逻辑手册,很难在php中复写一份。所以要在php中直接引用.NET的动态库就成了完成“任务”的关键

网上很多前辈记录了这个问题,但照葫芦画瓢未能成功,本文就是在“肝零工”的过程中,遇到并填坑的记录


生成COM组件动态库

COM component(COM组件)是微软开发的软件开发技术。其实质是一些小的二进制可执行程序,它们可以给应用程序,操作系统以及其他组件提供服务。而在php中如果想要引用第三方动态库,需要通过 new COM("Component.class") 的方法来实现,其中的 Component 必须是COM组件

1. 构建Windows类库项目

无论是哪个版本的Framework,应该都能够在Windows标签下找到类库项目
这样工程中默认会有 Properties\AssemblyInfo.cs 文件,里面记录了项目集所需的信息

2. 目标框架要匹配

创建项目的时候可以对Framework进行选择
如果是后期调整,可在工程属性 > 应用程序中的目标框架中进行修改
注意,需要于后期注册dll的时候的框架保持一致

3. 设置COM组件可见

Properties\AssemblyInfo.cs 文件中,将 ComVisible 进行如下修改

[assembly: ComVisible(true)]

4. 要设置签名并设置强名称密钥

工程属性 > 签名中,勾选 “为程序集签名” ,同时在下方 “选择强名称密钥文件” 中新建密钥文件

然后生成,在 bin\Debug 目录下找到对应的 dll 文件

5. 如果存在无法嵌入的动态库

假如工程Framework版本较低,或者,
引用的库缺少互操作所需特性,
总之,无法对引用库进行嵌入互操作

那么,依赖的dll,也需要执行后续的注册等操作


将DLL注册到服务器上

涉及到系统级的操作,坑甚多…

1. 确认php版本

亲测5.3.22版本不可用,5.4.5版本可用,所以尽可能采用5.4以上版本
现在php最高是8.0版了,不知道是否还是一样的操作方法

2. 确认所需系统工具

需要 gacutilregasm 两种工具,且都需要是 匹配Framework版本
也就是说生成的COM组件的dll用的是哪个版本的框架,此处也需要用对应版本的工具进行

通常情况下windows系统肯定会内置 regasm 工具
目录路径例如,
C:\Windows\Microsoft.NET\Framework64\v2.0.50727\RegAsm.exe
如果是应用于64位系统,则在Framework64 目录下,否则用 Framework 目录下,选择对应Framework框架的版本号,其中应该能找到 RegAsm.exe 文件

gacutil 工具在微软提供的 windows sdk 中有,如果没安装过,可点击到官网下载
默认安装后,Frameworkd4.0以下版本的工具路径,
C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\gacutil.exe
如果需要4.0的版本,路径是,
c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\NETFX 4.0 Tools\gacutil.exe

3. 配置php.ini

开启 com.allow_dcom = true
确保你的 extension_dir 目录中有 php_com_dotnet.dll 文件
开启或新增 extension=php_com_dotnet.dll

4. 缓存和注册DLL

以64位系统,4.0版本的my.dll为例

  • 将第一趴中生成的dll,复制到 c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\NETFX 4.0 Tools\ 目录中
  • 到目录 c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\NETFX 4.0 Tools\ 下执行 gacutil /i my.dll
  • 到目录 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ 下执行 regasm my.dll

5. 注销DLL

以64位系统,4.0版本的my.dll为例

  • 到目录 C:\Windows\Microsoft.NET\Framework64\v4.0.30319\ 下执行 regasm my.dll /unregister
  • 到目录 c:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\NETFX 4.0 Tools\ 下执行 gacutil /u my

php调用COM组件

以上内容都配置无误以后,就可以在php文件中进行调用,方法如下,

$comClass = new COM('namespace.className');
$comClass -> methodName();

提示没有COM方法,则需要考虑是否已经开启了php的com功能,或者php_com_dotnet.dll是否加载成功

提示没有调用的dll的方法,或者dll未注册,则需要考虑是否dll文件已经注册成功

最后被坑到半夜的我,愿大家调完bug都能早点睡


码字不易,如果喜欢,不用三连,点个赞👍便是最大的鼓励
欢迎关注微信公众号 "书咖里的曼基康"
书咖里的曼基康

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值