天天看点

c# Task.Factory.StartNew 传参数_【原创】Node.js调用C#动态链接库

c# Task.Factory.StartNew 传参数_【原创】Node.js调用C#动态链接库

有一种需求是在Web浏览器里面调用Windows程序,比如访问本地的打印机、读卡器等硬件。大家知道JavaScript本身是不具有这样的访问权限的,否则你只要浏览一个带病毒的网页,就可以把你本地的硬件都破坏了。

一种常见的思路,是把这个Windows程序的功能封装成C#动态链接库DLL,然后再编写一个Node.js服务(具体来说就是一个exe可执行程序),作为连接浏览器与DLL的桥梁。浏览器发送请求到Node.js服务,Node.js收到请求,去调用DLL。这样就解决了浏览器不能直接调用DLL的问题。用户的本地机器上需要运行这个Node.js服务,因此只有在用户本人同意这种方案的情况下,才可以采用,当然对于企业级的应用,用户肯定是同意的,因为这就是用户提的需求。

大家看到这个思路可能会问,为什么还要用Node.js和C#两种不同的技术呢? 本地用C#写一整套程序,既做HTTP服务器,又实现别的Windows功能,不就行了吗? 我相信那样也可以,但目前的现实是,Node.js搭建HTTP服务非常简便,上手难度较低,只要会JS就行,所以Node.js在这方面越来越成为主流。

在调用DLL之前,首先要知道你的DLL是32位还是64位。32位的DLL只能用32位的Node.js去调。只要Node.js的位数确定了,其余的相关组件会自动跟着Node.js,不用特别关注每一个组件的位数。

做的过程中,遇到的绝大多数问题,都是由于某个库的最新版本和另一个库的最新版本不兼容导致。 以下这些库的版本,是我反复一个一个试出来的。 只要版本对了,大多数的坑都可以避免。

所需库的版本

Node.js 8.2.1 32位

express.js 4.16.4 这个版本随意,用最新的即可

pkg 4.2.6

pkg-fetch v2.3-node-v8.0.0-win-x86

edge.js 7.10.1 此版本为最新版,作者已两年没更新。就是因为这个关键的库不更新,导致另外几个都要跟着它降版本。

用Express.js先搭一个简单的HTTP服务(百度即可)。

在app.js里引用edge库。

var 
           

让IDE自动导入和安装edge,然后进入工程下的这个目录,

node_modulesedgelibnativewin32ia328.2.1

这里面需要有三个文件,

node.exe

edge_nativeclr.node

edge_coreclr.node

IDE是不能自动把这三个文件安装进去的,需要手动拷进去。其中node.exe就是Node.js的主程序。另外两个.node格式的文件,在 https://github.com/agracio/edge-js 可以找到。

在app.js中定义一个变量,指向DLL中的函数。

var 
           

注意我这里把DLL的路径指定为bin/ ,在我的工程目录下面要有一个bin目录,里面放的是我要调用的DLL文件。

然后在程序中这样使用,

readIDCard 
           

就可以调用到DLL里面的函数了。

工程打包成exe方法:

1、首先确保Node.js工程在IDE中正常运行。

2、从Github镜像站下载依赖的pkg-fetch库

vercel/pkg-fetch​github.com.cnpmjs.org

c# Task.Factory.StartNew 传参数_【原创】Node.js调用C#动态链接库

如果这个镜像站也不行,参见 国内如何下载 GitHub release 中的内容?

这里我们下载 v2.3-node-v8.0.0-win-x86版本。这个版本号是和pkg 4.2.6相对应的。而pkg 4.2.6的版本号是我反复试出来的。

3、把第2步下载的文件放在本地缓存目录

C:Users你的用户名.pkg-cachev2.3

文件要改名,把uploaded改成fetched,最后文件全路径为

C:Users你的用户名.pkg-cachev2.3fetched-v8.0.0-win-x86

4、在Powershell或cmd中,定位到Node.js工程目录,执行打包exe命令

pkg -t win package.json

然后生成的exe文件会存放在同一个目录下。把生成的exe重命名为node.exe。(下一步要用到这个名字)

国外的用户可以跳过2、3两步直接进行第4步,国内因为不能直接从github下载所以需要那两步手工下载。

5、第4步生成的exe会去一个绝对路径下寻找依赖,如果你换台电脑,依赖就找不到了。这时候要用一个叫做rid的工具。

https://github.com/ironSource/rename-import-dll/releases​github.com

下载最新版0.0.2。

把rid.exe放在Node.js工程目录下。再把目录下的

node_modulesedgelibnativewin32ia328.2.1edge_nativeclr.node

这一个文件拷到工程目录下。

此时,rid.exe,edge_nativeclr.node,node.exe 这三个文件都在工程目录下。

6、在工程目录下,用cmd执行命令

rid.exe edge_nativeclr.node node.exe programName.exe
           

其中programName.exe是你任意起的名字。

这一步的结果并不是生成一个叫programName.exe的文件,而是往edge_nativeclr.node文件里面写入了一些东西。 观察一下edge_nativeclr.node文件的修改时间是不是刚刚。

7、把工程目录下的bin目录、edge_nativeclr.node、node.exe这两个文件,拷到一个新的目录中。 把node.exe手工重命名为programName.exe。 最终你的目录是下图这个样子的。

c# Task.Factory.StartNew 传参数_【原创】Node.js调用C#动态链接库

至此,大功告成。不管你把它们三个拷到哪里,只要另外那两个东西跟着这个exe,这个exe就可以正常运行。