考勤 指纹 php,折腾中控指纹签到SDK始末(.net监听) | quericy Eden*

Reflector

先尝试

1copy .\*.dll %windir%\System32\

2regsvr32 %windir%\System32\zkemkeeper.dll

我就不吐槽官方的包把system32写成小写了…

然后看看Demo…有P/Invoke的全称是Platform Invoke (平台调用) 它实际上是一种函数调用机制,通过P/Invoke可以调用非托管DLL中的函数.于是里面没有啥对我们有用的代码,核心函数全在那些c++的dll里.不过姑且还算

谷歌了下网上的php调用.net的dll教程.基本上都是dll自己写的或者是有源码的,但是我手头只有一个孤零零的P/Invoke的dll,怎么办呢?

dll

由于用reflector看了下发现assembly中没有ComVisible项,于是用dll

这里需要先给reflector安装Reflexil插件.重启reflector后,先选择需要的dll,然后打开Tools->Reflexil v1.5,在Custom attributes选项卡中右击Create New,在Attributes选项卡中,Constructor找到mscorlib->CommonLanguageRuntimeLibrary->System.Runtime.InteropServices->ComVisibleAttribute,选择.ctor,如图所示:

47455365_1.png

同理,在Constructor arguments选项卡中,Type找到mscorlib->CommonLanguageRuntimeLibrary->Boolean并选择,Specification选Default,Arg.type选Boolean,Argument手动输入True并确定.

最后在类上右击,找到Reflexil->Save as,就可以导出

强命名签名文件

木有项目文件,只有一个dll,怎么做强命名签名?还是有办法的:

为没有源码的DLL文件添加强名称:

1sn -k Interop.zkemkeeper.snk  //创建一个新的随机密钥对

2

3ildasm Interop.zkemkeeper.dll /out=Interop.zkemkeeper.il   //反编译目标程序集

4

5ilasm Interop.zkemkeeper.il /dll /resource=Interop.zkemkeeper.res /key=Interop.zkemkeeper.snk /optimize

6//重新编译,附带强命名参数

ok,这个时候的dll就是带

注册.netdll并添加到全局程序集缓存

以管理员身份运行vs的命令提示符工具:(一般在Visual Studio Tools中有个Visual Studio 命令提示)

1sn -v Interop.zkemkeeper.dll

2//验证签名信息(这一步可省略)

3regasm  Interop.zkemkeeper.dll

4//注册COM组件

5gacutil /I Interop.zkemkeeper.dll

6//将程序集添加到全局程序集缓存中

如图所示就代表成功了:

47455365_2.png

1regasm /regfile Interop.zkemkeeper.dll

这步只是为了看我们之前注册组件的时候在注册表的位置.

打开regedit,找到reg文件里记录的{xxxx..}这样的键,展开,找到47455365_3.png

php调用.net dll:

首先php需要开启com_dotnet,在php.ini中开启插件:

1[COM_DOT_NET]

2extension=php_com_dotnet.dll

然后php中便可调用了,方法类似如下:

1$r=new Com("刚才获得的ProgID");

2$s=$r->类的方法();

3echo $s;

–悲剧的分割线–

当然,以上是理想状态下,实际情况是,我在前面都成功的情况下,最后调用仍然报错了:

0x80040154 没有注册类

(╯‵□′)╯︵┻━┻

谷歌了半天,最后觉得仍然是如果有谁知道请务必告诉我_(:з」∠)_)

于是迫不得已只能用另一种方法了,那就是

使用WinForm监听http

先引用Interop.zkemkeeper.dll,然后写个方法GetData.test()按照Demo的事例抓取需要的数据(此处略);

winform使用端口监听还是蛮方便的,一个后台线程就能搞定:

1private Thread _t;

2private HttpListener _listerner =new HttpListener();

3

4private void StartBackWork( )

5{

6if (!_listerner.IsListening)

7using (_listerner =new HttpListener())

8{

9_listerner.AuthenticationSchemes = AuthenticationSchemes.Anonymous;//指定身份验证 Anonymous匿名访问

10try

11{

12_listerner.Prefixes.Add(textBox1.Text.Trim());

13}

14catch (ArgumentException)

15{

16MessageBox.Show("地址不合法!","错误", MessageBoxButtons.OK, MessageBoxIcon.Error);

17return;

18}

19try

20{

21_listerner.Start();

22}

23catch (HttpListenerException e)

24{

25MessageBox.Show("启动失败:\n" + e.Message,"警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);

26return;

27}

28string[] ipstr = richTextBox1.Text.Split(',');

29foreach (string sin ipstr)

30{

31if (s.Trim()=="")

32{

33MessageBox.Show("IP不能为空","警告", MessageBoxButtons.OK, MessageBoxIcon.Warning);

34return;

35}

36}

37

38

39label2.Text ="已启动";

40richTextBox1.ReadOnly =true;

41textBox1.ReadOnly =true;

42MessageBox.Show("监听启动成功","提示", MessageBoxButtons.OK, MessageBoxIcon.Information);

43while (true)

44{

45//等待请求连接

46//没有请求则GetContext处于阻塞状态

47HttpListenerContext ctx = _listerner.GetContext();

48ctx.Response.StatusCode = 200;//设置返回的http状态代码

49string name = ctx.Request.QueryString["name"];

50

51if (name !=null)

52{

53Console.WriteLine(name);

54}

55

56

57//使用Writer输出http响应代码

58using (StreamWriter writer =new StreamWriter(ctx.Response.OutputStream))

59{

60//writer.Write("aaa");

61

62writer.Write(GetData.test(ipstr));

63

64writer.Close();

65ctx.Response.Close();

66}

67

68}

69}

70}

当然,为了不卡UI,我们要新建一个Thead来运行它:

1if (!_listerner.IsListening)

2{

3_t =new Thread(StartBackWork);

4_t.Start();

5}

这样,当这个程序运行着的时候,就能监听指定的本地http地址(如localhost),如果其他机器或者php访问请求,就可以触发事件,该程序调用那几个COM组件去考勤机上取数据,最终返回给http请求方.

47455365_4.png

参考文章:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值