[新手上路]批处理新手入门导读[视频教程]批处理基础视频教程[视频教程]VBS基础视频教程[批处理精品]批处理版照片整理器
[批处理精品]纯批处理备份&还原驱动[批处理精品]CMD命令50条不能说的秘密[在线下载]第三方命令行工具[在线帮助]VBScript / JScript 在线参考
返回列表 发帖

[原创代码] Bridge.js v1.0.3 跨进程通信方案

本帖最后由 CrLf 于 2015-10-6 14:52 编辑
Bridge.js  基于 NodeJS 的跨进程通信方案  1.0.3  [http://www.bathome.net]

"f:\nodejs\Bridge\node.exe"  "f:\nodejs\Bridge\Bridge.js"

                [/gbk] [/alone] [/unsafe] [/debug] [/help]
                [IPv4 | Port | IPv4ort]
                OPTION [name] [value1] [value2] ...


        /gbk        改用 gbk 编码输出,不使用则默认为 utf-8 编码
        /alone        启用将禁止守护进程,在异常退出时不会自动重启
        /unsafe        允许非管理员用户服务器端执行不安全的命令
        /debug        调试选项
        /help        显示这个帮助

        [IPv4 | Port | IPv4:Port]
                指定目标 ip 地址和端口,可以仅指定其中一个
                默认 IPv4 = 127.0.0.1                端口 = 8848
                对 server 命令来说,此处指定的 IPv4 为管理员
                若未启用 /unsafe 开关,仅有管理员可以使用 remote 命令


        OPTION        可用的命令如下:
                --------------------------------------------------
                [本地]        server        eval        test        search        match
                        replace

                [交互]        get        set        delete        defined        cmp
                        name        value        list        sort        until
                        config        pipe        exec        eval
                        remote        log        listen        exit
                --------------------------------------------------

                本地命令仅由客户端执行,交互命令需与服务器端交互
                具体用法如下,带 * 标记的 OPTION 为交互命令

        server [IP1] [IP2] ...
                核心命令,使用后将启用一个服务器端,监听指定的 Port 端口
                若未使用 /alone,将启用进程守护
                可以用 IP1 ... IPN 指定允许接入的 IP 列表,支持通配符 * 和 ?
                若未指定 IP 列表,则接受任何来源的客户端连接

     *        get name
                从服务器获取指定变量的值

     *        set name [value]
     *        set name [value1] [value2] ...
                为 name 设置一个变量 value
                若 value 不止一个,将保存为 name[1]...name[N] 的伪数组形式

     *        defined name
                判断是否存在以 name 为名的变量

     *        delete name
                删除以 name 为名的变量

     *        cmp name value
                判断以 name 为名的变量是否等值于 value

     *        name [name]
                返回以 name 开头的变量名

     *        value [name]
                返回以 name 开头的变量值

     *        list [name]
                返回以 name 开头的变量名和变量值

     *        sort [name]
                对变量排序,伪数组按照数字顺序排列
                若指定了 name,将只排序以 name 开头的变量

     *        until name [value] [timeout] [millisec]
                循环读取 name 值,直到满足以下逻辑:
                1、无 value 时等待直到变量值不为空
                2、有 value 时等待直到变量值等于 value
                3、有 timeout 时最多只会等待 timeout 毫秒,不大于 0 则无限等待
                4、有 millisec 时以指定毫秒数为周期发送查询请求,默认 100ms

        test string (pattern | /pattern/mode)
                判断 string 是否符合 pattern
                pattern 可以为正则表达式或字符串,下同

        search string (pattern | /pattern/mode)
                返回 string 中首次匹配到 pattern 的位置

        match string (pattern | /pattern/mode)
                罗列 string 中符合 pattern 的的结果

        replace string1 (pattern | /pattern/mode) string2
                将 string1 中符合 pattern 的部分替换为 string2

     *        config name [value]
                返回服务器端的 CONFIG[name]
                若指定了 value,则会将其设置为 value
                若未启用 /unsafe 开关且非管理员,服务器端将拒绝 value 设置

                可以通过 config 设置的值:
                    unsafe/false/alone/quiet/debug - 对应同名开关[布尔值]
                    host/port - 要连接的目标 IP 与端口[字符串]
                                在 server 命令下则是此后新增监听端口的管理员 IP
                    defaultlogname - 默认日志名称[字符串]
                    charset/__localCharSet__ - 字符编码名称,不建议修改[字符串]
                    __clientTimeout__ - 客户端循环 POST 的时间间隔[正整数]
                    __maxBuffer__ - 传递数据时的容量[正整数]

     *        pipe in [name]
     *        pipe out [name]
                为两个进程连接模拟管道,in 为入口,out 为出口
                name 为管道名称,只有使用相同名称的请求可以对接
                若不指定 name 则使用默认管道
                允许传送的长度由 CONFIG.__maxBuffer__ 控制

     *        exec command [timeout]
                在服务器端执行 cmd /c "command",并返回执行结果和退出码
                若未启用 /unsafe 开关且非管理员,服务器端将拒绝执行 code

        eval code
                执行 code,并返回执行结果

     *        remote code
                在服务器端以 JavaScript 执行 code,并返回执行结果
                若未启用 /unsafe 开关且非管理员,服务器端将拒绝执行 code

     *        log text [filename]
                在服务器端记录一条日志,内容为 text,文件名为 filename
                若不指定 filename,则默认为 "Bridge_服务器端启动时间"

     *        listen
                让服务器新增要监听的目标端口

     *        exit [exitcode]
                结束服务器端脚本,退出码为 exitcode


        注意事项:

                参数中的 " 需写为 \" 或 "",否则将被丢弃
                如 "say:""hello.""" 实际等于 say:"hello."

        EXITCODE 的含义:

                0 正常退出
                1 参数错误
                2 服务器端传回 stderr
                3 命令内部自定义的错误
                4 POST 连接错误
                5 全局捕获的错误
                6 NodeJS 模块加载失败
                7 使用 WSH 宿主运行时发生的错误

东西有点大,主要是 NodeJS 及 iconv-lite 模块比较肥,没必要占用论坛空间,放百度网盘了
Bridge 主文件下载地址:
http://pan.baidu.com/s/1qWpDASs
因为需要同时兼容 node/wscript/cscript 宿主,只能将中文转码为 \uXXXX 格式,这里是原始代码及转码脚本:

第一次写 Node 脚本,各种回调用得很不直观,而且代码习惯很差,风格太难看,见谅

----------------------------------------   版本说明   ----------------------------------------

    2015/09/27    原始版本
                  实现了变量传递部分
                  合并服务器端、客户端

    2015/10/03    v1.0
                  兼容 WSH
                  整合大量命令
                  重整代码结构
                  增加错误处理功能

    2015/10/04    v1.0.1
                  完善错误处理,增强容错能力
                  增强在 CScript 宿主环境下使用管道的可靠性
                  在 CScript/WScript 宿主环境下不再依赖 iconv-lite 库
                  细化退出码含义
                  伪数组的序号改为从 0 开始
                  其他微调

    2015/10/05    v1.0.2
                  修正判断 IP 权限时的错误

    2015/10/05    v1.0.3
                  修正参数解析逻辑与帮助不符的错误
附件: 您需要登录才可以下载或查看附件。没有帐号?注册
2

评分人数

本帖最后由 CrLf 于 2015-10-6 14:53 编辑

----------------------------------------   简要说明   ----------------------------------------

    Bridge.js 用于跨进程、跨主机交互,基于 NodeJS,必须有 Node.exe 才能运行。
    只要创建一个可访问的服务器端,不同进程乃至网内的不同机器都可以轻松地在命令行下协同工作,目前已实现变量读写、管道连接、远程日志等功能,并能通过高级命令进行更详细的操作
    默认输出为 utf8 编码,直接上屏时无需设置,但需要重定向或进入管道时,建议开启 /gbk 开关以获得输出,或使用 CScript 执行
    进程意外中止时,守护进程会重新启动服务器端,并还原关键数据
    命令行参数中单独出现的双引号会被忽略(编译器特性,非脚本行为),需要保留双引号时请写为 \" 或  ""
    option 之后的参数默认支持以 %varName% 形式引用环境变量,若要关闭此特性,请使用 /env 开关


----------------------------------------   兼容宿主   ----------------------------------------
   
    此代码经过兼容处理,也可以在 WScript、CScript 宿主下调用,但仍需要 NodeJS 支持,而且行为细节将有所变化:
    CScript 环境下,无论是否启用 /gbk 开关,都将输出为 gbk 编码(node下默认为 utf8),但比直接调用 Node.exe 稍慢,且必须等待进程结束才能看到输出,建议在需要不确定是输出到屏幕还是重定向到文件时使用
    WScript 环境下,除非需要查看帮助信息(例如使用了 /help 开关),否则将始终后台静默运行,建议在不需要回显和等待结果的场合使用


----------------------------------------   基本用法   ----------------------------------------

    [创建服务器端]
  1.     node.exe Bridge.js server 192.168.0.* 192.168.2.*
  2.     ::创建一个服务器端,默认监听端口为 8848,默认管理员 IP 为 127.0.0.1
  3.     ::IP 为 192.168.0.* 或 192.168.2.* 的用户均可接入,但不能进行风险操作
  4.     Bridge.js server 192.168.0.* 192.168.2.*
  5.     ::参数与前例一样,不过是由 WScript 宿主启动,在后台静默运行
复制代码
[日志功能]
  1.     node.exe 192.168.0.1 Bridge.js log Text FileName
  2.     ::客户端命令 IP 为 192.168.0.1 的服务器端记录一条日志
  3.     ::内容为 Text,保存在 FileName.log 中
复制代码
[遥控功能]
  1.     node.exe 192.168.0.1 Bridge.js exit 12
  2.     ::客户端命令 IP 为 192.168.0.1 的服务器端退出脚本,且退出码为 12
  3.     ::若服务器端未使用 /unsafe 开关,exit/config/remote 命令只能由服务器端管理员执行
  4.     node.exe 8848 Bridge.js config unsafe
  5.     ::查看通过 8848 端口查看本机响应服务器端的 unsafe 设置
  6.     ::任意命令均可以 [IP]:[端口] 或 [IP] 或 [端口] 的方式执行
  7.     ::除 server 命令和无需与服务器交互的命令外,都会连接指定的 IP 和端口
  8.     node.exe Bridge.js config unsafe true
  9.     ::命令服务器端将 unsafe 设置改为 true,相当于开启了 /unsafe
  10.     ::能通过 config 开启的开关有:
  11.     ::    unsafe/false/alone/quiet/debug - 对应同名开关[布尔值]
  12.     ::    host/port - 要连接的目标 IP 与端口[字符串]
  13.     ::                在 server 命令下则是此后新增监听端口的管理员 IP
  14.     ::    defaultlogname - 默认日志名称[字符串]
  15.     ::    charset/__localCharSet__ - 字符编码名称,不建议修改[字符串]
  16.     ::    __clientTimeout__ - 客户端循环 POST 的时间间隔[正整数]
  17.     ::    __maxBuffer__ - 传递数据时的容量[正整数]
复制代码
[变量读写]
  1.     node.exe Bridge.js set varName varValue
  2.     ::客户端A发送一个消息,将变量 varName 设为 varValue
  3.     node.exe Bridge.js defined varName
  4.     ::客户端B判断服务器上是否存在变量 varName
  5.     node.exe Bridge.js get varName
  6.     ::获取变量 varName 的值 varValue
  7.     node.exe Bridge.js set Array Value1 Value2 Value3
  8.     ::创建一个从 0 开始伪数组,名字为 Array[0]~Array[2],值分别为其后参数
  9.     ::Value 多于一个的时候才会触发数组设置,设置前会清除原有同名数组
  10.     node.exe Bridge.js delete Array[1]
  11.     ::删除名为 Array[1] 的变量
  12.     node.exe Bridge.js sort Array
  13.     ::对名称以 Array 开头的变量进行排序
复制代码
[管道功能]
  1.     dir | node.exe Bridge.js pipe in
  2.     ::客户端A使用管道发送 dir 命令的输出
  3.     node.exe Bridge.js pipe out
  4.     ::客户端B从管道中接收输出
  5.     dir | node.exe Bridge.js pipe in Name1
  6.     ::打开一个名为 Name1 的新管道,否则默认使用空字符为管道名
  7.     node.exe Bridge.js pipe out Name2
  8.     ::同名管道不能同时接受两个 in 或 out,通过管道名可以同时使用多个管道
复制代码
[重定向实例]
  1.     node.exe Bridge.js /gbk eval "'abcdefg'.replace(/./g,'$&\n')" | findstr /n .
  2.     ::在本地进行重定向(包括进入管道)时,请开启 /gbk 开关
  3.     cscript -nologo Bridge.js eval "'abcdefg'.replace(/./g,'$&\n')" 2>nul | findstr /n .
  4.     ::也可通过 cscript 调用,则默认将输出转为 gbk 编码
  5.     ::因为需要区分 cscript 和 wscript,所以会在句柄 stderr 中输出一空行
复制代码
[本地增强]
  1.     node.exe Bridge.js eval 16*7.5
  2.     ::在客户端上计算并返回 16*7.5 的结果,无需与服务器端交互,也无权限限制,可以执行复杂的命令
  3.     ::eval 与 remote 命令相似,区别在于 remote 命令是在服务器端执行,需要有相应权限
  4.     node.exe Bridge.js replace Striing i ""
  5.     ::将 Striing 中的 i 替换为空,仅替换首个符合的位置
  6.     node.exe Bridge.js replace String /.*/ """$&"""
  7.     ::将 String 中符合正则表达式 /.*/ 的部分加上左右双引号,要保留的双引号需复写
  8.     ::replace/match/test 命令仿照 JavaScript 的参数格式设置,均同时支持正则表达式和字符串匹配
复制代码

TOP

本帖最后由 CrLf 于 2015-10-4 03:55 编辑

其实如果改成必须通过 cscript 运行的话,完全可以用 adodb.stream 代替 iconv-lite 库,这样就只需要 Node.exe 和 Bridge.js 了,但会比直接使用 node.exe 要多调用一个进程,减小体积的代价是牺牲了一点效率,大伙有兴趣的来说说这样值得吗...
我是觉得反正都要下载 10MB 的 node.exe 了,多一个 371KB 的文件夹也只算九牛一毛了

-------------------------------------------------------------------------------------------------------------------------
已经改成支持 node/wscript/cscript 多种宿主启动的了,修改后,仅在直接用 node.exe 执行时需要 iconv-lite 模块,wscript.exe 运行时看不到输出所以不需要转码,而用 cscript.exe 运行时则改用 adodb.stream 控件进行转码
cscript 的输出是 gbk 的,可以任意重定向,但因为需要等 node 运行完毕才能取得回显,所以建议在 server 端使用 wscript 或 node,而客户端则看情况,详见 2 楼的《兼容宿主》部分

TOP

[创建服务器端]
第3行说明文字两个IP地址一样,都是 192.168.0.*。有个小疏漏^_^

[本地增强]
第8行引号"可以直观一点,使用转义\"
node.exe Bridge.js replace String /.*/ """$&"""
node.exe Bridge.js replace String /.*/ \"$&\"

其实想问的是,XP能用么?
1

评分人数

    • CrLf: 感谢指正技术 + 1
如无特别说明,代码测试环境均为 XP SP3

TOP

回复 4# cutebe


    感谢指正
    第一个问题已经更正
    第二个问题我还真不知道可以这么写,但考虑到复写双引号基本可以不考虑特殊字符,所以两个写法都不错
    第三个问题没考虑过,基础功能是在 win7 下测试通过的,其后添加的功能在 win8 下边写边测试的,整个架构基于 post 通信,我想 xp 应该也没啥问题,不过因为 nodejs 毕竟是运行在服务器系统上的,在老版本系统的 windows 下的确可能存在差异

TOP

本帖最后由 chouxia 于 2015-10-5 11:07 编辑

回复 5# CrLf


    这个日志部分能不能改动一下?
start cmd /c "node.exe Bridge.js server 192.168.0.* >>%date%.log 2>&1"
能不能按这个方法运行?
这样,跨日期的日志就可以自动换文件了。方便日志查找,也方便控制日志大小

TOP

回复 5# CrLf


    还有,测试的过程有点问题
start cmd /c "c:\node\node.exe c:\node\Bridge.js server 192.168.0.* >>c:\log\1.log 2>&1"
这个命令启动server
然后server本机
C:\node>node.exe c:\node\Bridge.js log testlog test.log
Error: 被阻止
C:\node>node.exe c:\node\Bridge.js log testlog
Error: 被阻止

C:\node>node.exe c:\node\Bridge.js log testlog c:\log\test.log
Error: 被阻止
远程机器访问:
D:\node>node d:\node\bridge.js 192.168.0.195 log testlog test.log
Error: 未捕获错误 "Error: connect ETIMEDOUT 192.168.0.195:8848
    at Object.exports._errnoException (util.js:837:11)
    at exports._exceptionWithHostPort (util.js:860:20)
    at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1060:14)"
服务器2012 server  工作站 win7
1

评分人数

    • CrLf: 感谢指正技术 + 1

TOP

回复 7# chouxia


这部分的逻辑写反了,已修正,感谢指正
至于日志格式,楼上自行修改 logAppendLine 函数吧,这个函数负责解析参数输入并输出到文件,或者你也可以自行用其他脚本定期对日志格式化分类
因为宿主特性和应用环境比较特殊,很难权衡如何输出,考虑到服务器端需要有较高的稳定性,我目前的结构倾向于方便调试跟踪,参数格式也尽量简单化,而未考虑太多的个性化设置,但为有能力进行高级设置的用户预留了 remote 命令,可以随时改变软件行为,但这些行为可能在不同版本中失效(因为在新版本中可能会修改脚本逻辑或函数名)

TOP

返回列表