admin管理员组文章数量:1565292
AppEmit 中间件 说明书
程序名称 |
AppEmit.exe |
|
程序版本 |
v1.0.0 |
|
说明书版本 |
v1.0.0 |
|
网址 |
http://www.appemit |
|
|
appemit@appemit |
|
修改时间 |
2020年8月29日 |
|
修订 |
v1.0.3 |
- 概述
AppEmit是应用程序(尤其是浏览器)与本地程序间互相通信的易扩展的轻量级中间件。
AppEmit is an extensible lightweight middleware for communication between applications (especially browsers) and local programs.
主要采用了HTML5国际标准的Web Socket进行通话,默认为异步, JSON格式传递参数。
- 主要功能:
- 在几乎所有浏览器播放含有flash的网页或Flash文件,包括swf交互动画、flv影视等
- 在浏览器打开、操作本地文件,比如阅读PDF;创建、阅读、编辑Office文件,且支持JavaScript代码操作
- 在浏览器中调用第三方DLL、OCX等ActiveX组件以及系统winApi函数,tcc、python、lua等
- 开发本地硬件DLL的插件,实现在网页中操作控制本地的读卡器、打印机、扫描仪、高拍仪、U盾等各种硬件设备
- 各个应用程序之间通信,比如聊天
- 在Chrome里嵌入IE内核网页,保护源码,可以不修改原有的ActiveX读取html,同时支持开源内核wke和blink
- 解决问题
- 国际市场份额68%以上的chrome浏览器(数据来源Netmarketshare;国内25%以上)在2020年12月后不再支持flash,而微软的edge也不支持ActiveX。
- 客户习惯使用浏览器来处理各种业务。
- 游戏商、银行、医院、电力、硬件等企业客户在各种浏览器中开发调用dll、ocx、ActiveX、com组件、flash等文件的场景需要。
- 相关链接
程序名称 AppEmit.exe
网址 AppEmit是应用程序(尤其是浏览器)与本地程序间互相通信的易扩展的轻量级中间件
Github https://github/appemit/appemit
Email联系 appemit(at)appemit
内容分发下载地址 github下载
-
- 具体功能
支持同步、异步(默认)处理消息或者消息组
支持一个页面打开多个APP
支持本地文件和网络文件访问
支持获取硬件信息,包括系统、CPU、主板、显卡、内存、硬盘、网络等
支持USB监控
支持pcomm串口异步多线程调用
支持用户间通信、发送接收消息
支持使用IE、webkit、blink内核打开,互动网页
支持打开、互动flash,包括ActiveX flash和NPflash
支持多媒体播放
支持打开、编辑、代码互动microsoft office、金山office的world、excel、ppt,支持本地文档和网络文档处理
支持打开PDF
支持调用第三方dll、com等链接库
支持开发dll等
-
- 使用条件
- 系统
- 使用条件
Windows系统,支持XP以上。
软件/插件 |
功能/方式 |
依赖条件 |
说明 |
AppEmit |
Windows系统XP以上 |
32位, 可以运行在x64、 x86上 |
|
flash |
调用本地flash AcitveX控件,打开swf文件 |
本地安装flash AcitveX控件 |
|
打开网络中含有swf的网页 打开网络中的文件swf |
自动安装插件 |
或者下载完全插件版本可局域网使用。后续同。 |
|
IE |
打开网络中含有swf的网页 采用不同内核IE\webkit打开网络或者本地网页 |
- |
|
|
阅读网络或者本地PDF文件 |
- |
|
Office |
打开、编辑Office文档 |
本地安装Office |
|
媒体文件 |
打开网络中的文件 视频格式:mp4、flv、m3u8、rtmp 视频编码:H.264 音频编码:AAC、MP3 音频格式:MP3等文件 |
- |
-
-
- 用法
-
在windows系统中,下载免安装程序AppEmit(不含插件小于6M),运行AppEmit.exe即可。设置了开机自启动,应避免被杀毒软件关闭。
同时只能开启一个AppEmit.exe进程。
-
- 技术实现
- 技术依赖
- 技术实现
采用开源或公共控件,安全可靠。
- Web Socket采用开源控件HPSocket(https://github/ldcsaa/HP-Socket),支持ssl。
Dll文件开放了C接口,可以在此基础二次开发控件,主要调用
- HPSocket4C_U.dll
- HPSocket4C-SSL_U.dll
- IE内核调用flash Active控件
- 非IE内核调用flash NPAPI控件
- webkit内核采用开源软件wke控件
- blink内核采用开源软件miniblink控件
-
- 步骤
-
- 网页注册后获得设置cid,clientKey,获得连接授权。或者使用临时账户cid=00000-1测试。
一个账户cid目前最多15个,设置cid后不要任意修改,更新数据有1-2小时延迟。
- 连接Appemit服务
AE_initAppWs("ws://localhost:80/appemit?cid=00000-1&sid=1&flag=1")
- 设置clientKey授权,(clientKey为私有,发布后需要保密混淆加密js)初始化数据以及授权等
var AE_initSet = {
"emit":"init",
"clientKey": "temp-0000000000", //
"clientInfo":clientInfo,
"wsUrl": wsUrl,
// "flag":0,
// "sid":"123456", // 用户session 或者用户名ID,唯一可以准确通话
"gid": "[1,2]", //用户群ID,一个用户可以加入多个群
// "utf_escape":false, //默认false, 反馈的data编码转义
};
AE_EmitReq_PIP(AE_initSet);
- 发送命令
AE_OpenApp('{"emit":"hardWare","Obj":"pc","par0":{"dev":["os","base"]}}')
-
-
- demo
-
在demo下主要是html的举例,
- 包括获取pc信息,实现通话的index.html
- 以及播放flash的AppEmbed.html
- 联系
邮件: appemit@appemit
- 插件场景用法
- 获取客户端信息
使用浏览器打开demo下的index.html。授权连接后,发送获取PC信息命令。
AE_initAppWs("ws://localhost:80/appemit?cid=00000-1&sid=1&flag=1")
AE_OpenApp('{"emit":"hardWare","Obj":"pc","par0":{"dev":["os","base"]}}')
-
- 不同客户端通信
打开demo下的index.html,模拟不同sid打开浏览器。
连接Appemit授权后,在sid=1下发送命令。
{"emit":"msg", "Obj":"sid","toSids":["2"],"toGids":[1,2],"data":"hi, I am Tom."}
在客户cid全集下,通过唯一的sid对话,可以一对一,或者一对多通话。
图为1对2和3通话。
另外还可以设置不同群gid,一个sid可以加入不同的gid。
发送消息时,在cid全集下,所有的toSids和toGids取对应的sid交集剔重,并排除自身。
-
- 打开文件
已系统默认的程序,打开文件。
为了安全,不支持直接打开的类型包括
{"exe";"msi";"cmd";"js";"jar";"inf";"com";"scr";"reg";"bat";"vbs";"py"}
发送命令打开文件,以独立的方式打开,和浏览器没有关系。
{"emit":"open", "Obj":"file","AppShow":false,"src":["/demo/htmlDemo/file/d1.docx",null,null,1]}
src:EXE文件路径, 启动参数="",操作类型 = "open",显示属性 _SW_,工作目录=""
-
- Flash
两种方法,主要四种形式实现场景
- 使用客户端本地安装的Flash Player ActiveX控件,要是客户端没有,需要自行下载。下载地址:http://www.adobe/go/getflashplayer
- 使用Appemit程序自带的插件plugins/NPSWF32.dll
-
-
- NPAPI-嵌入web
-
能打开常用网页,目前的插件不支持html5的媒体特性。如有需要,可以使用node或者electron插件。
使用webkit内核使用Appemit程序自带的插件NPSWF32.dll,能打开嵌有flash的网页,不默认具有右键菜单。
连接授权后,发送命令"AppType":1的形式。
{"emit":"open","Obj":"flash","AppType":1,"src":"http://sxiao.4399/4399swf/upload_swf/ftp14/yzg/20140328/bombit7/zx_game7.htm","pos":1}
-
-
- NPAPI-网络flash文件
-
使用Appemit程序自带的插件NPSWF32.dll, 打开网络flash文件。
连接授权后,发送命令"AppType":2的形式。
{"emit":"open","Obj":"flash","AppType":2,"src":"http://sxiao.4399/4399swf/upload_swf/ftp18/liuxy/20160130/17801/game.swf","pos":1,"par0":{"autoPlay":true,"loop":true,"quality":"high","wmode":"Transparent"}}
-
-
- NPAPI-网络媒体文件
-
使用Appemit程序自带的插件NPSWF32.dll, 打开网络媒体文件,包括flv,mp4等。
连接授权后,发送命令"AppType":3的形式。
{"emit":"open","Obj":"flash","AppType":3,"src":"https://media.html5media.info/video.mp4","pos":1,"par0":{"autoPlay":1,"loop":1}}
-
-
- ActiveX形式
- 打开网络flash文件
- ActiveX形式
-
打开demo下的AppEmbed.html,连接授权后,发送使用ActiveX("AppType":4)打开网络flash文件命令,参数如下。
{"emit":"open","Obj":"flash","AppType":4,"src":"http://img1.yo4399/swf/00/0ff035e0e96584c07df65ab3636f72.swf","pos":1,"par0":{"autoPlay":1,"toolbar":0,"rightMenu":0,"hitCaption":0,"hideStop":0,"loop":1,"volumeMute":0,"flashVars":"a=0&b=0&c=SetInSrc"}}
注意事项:
在客户端需要下载安装flash player ActiveX。
路径是 / 或许 \\
flashVars可以设置在src中
AppType正数为嵌入APP,负数为浮动窗口,后同。
刷新即可关闭flash
-
-
-
- 打开本地flash文件
-
-
可以是绝对或者相对路径,相对于AppEmit.exe的路径:"demo/htmlDemo/test1.swf"。
{"emit":"open","Obj":"flash","AppType":4,"src":"demo/htmlDemo/test1.swf","pos":1,"par0":{"autoPlay":1,"toolbar":0,"rightMenu":0,"hitCaption":0,"hideStop":0,"loop":1,"volumeMute":0,"flashVars":"a=0&b=0&c=SetInSrc"}}
-
-
- 关闭
-
- 刷新即可关闭flash
- {"emit":"close","AppId":1} //空时默认追加AppId 1
- {"emit":"closeAll"}
- Web
具有右键菜单。
-
-
- IE 内核
-
"AppType":1使用IE内核打开网页
{"emit":"open","Obj":"web","AppType":1,"pos":1,"par":{"htmlStr":null,"HttpServer_startUrl":null,"URL":"http://www.appemit"},"par0":{"header":null,"noScriptErr":true, "UIFLAG":null,"DLCTL":null,"userAgent":null,"crossDomain":true}}
设置htmlStr可以直接打开html源码。
设置HttpServer_startUrl,可以打开本地的html文件。
设置URL打开网页。 三者优先级依次下降。
-
-
- Webkit内核
-
"AppType":2使用webkit开源内核打开网页
{"emit":"open","Obj":"web","AppType":2,"pos":1,"par":{"htmlStr":null,"HttpServer_startUrl":null,"URL":"http://www.appemit"},"par0":{"header":null, "userAgent":null,"crossDomain":true,"downLoad":1}}
设置htmlStr可以直接打开html源码。
设置HttpServer_startUrl,可以打开本地的html文件。
设置URL打开网页。 三者优先级依次下降。
-
-
- blink内核
-
"AppType":3使用开源blink内核(webkit加强版)打开网页,可以浏览网页,支持前进 后退 刷新 复制 粘贴,支持下载。
{"emit":"open","Obj":"web","AppType":3,"pos":1,"par":{"htmlStr":null,"HttpServer_startUrl":null,"URL":"http://www.appemit"},"par0":{"header":null, "userAgent":null,"crossDomain":true,"downLoad":1}}
设置htmlStr可以直接打开html源码。
设置HttpServer_startUrl,可以打开本地的html文件。
设置URL打开网页。 三者优先级依次下降。
-
- office
- office
"AppType":4使用开源blink内核打开阅读PDF文件,支持本地和网络PDF。
{"emit":"open","Obj":"web","AppType":4,"pos":1,"par":{"URL":"/demo/AppEmit_help.pdf","par0":{"rightMenu":1}}}
设置URL打开PDF文件。
-
-
- Office
-
使用微软com技术创建、打开阅读、编辑Office,包括word\excel\PPT文件,支持本地和网络文件。
支持在javaScript中添加类似VBA代码动态控制,同时可以在浏览器网页里执行命令。
-
-
- Wps
-
使用 com技术创建、打开阅读、编辑金山wps ,包括wps\et\wpp文件,支持本地和网络文件。
支持在javaScript中添加类似VBA代码动态控制,同时可以在浏览器网页里执行命令。
-
-
- Office DsoFramer (不稳定)
-
使用微软开源控件DsoFramer创建、打开阅读、编辑Office,包括word\excel\PPT文件,支持本地和网络文件。
{"emit":"open",
"Obj":"office",
"AppType":1,
"src":"/demo/htmlDemo/file/x1.xls",
"pos":1,
"par0":{"Caption":true,
"ProtectDoc":0,
"Toolbars":true,
"btnFile":true,
"MNU_NEWBLANK":0,
"MNU_NEW":0,
"MNU_OPEN":0,
"MNU_CLOSE":0,
"MNU_SAVE":0,
"MNU_SAVEAS":0,
"MNU_PGSETUP":0,
"MNU_PRINT":0,
"MNU_PROPS":0,
"show_UpdateTool":true}
}
设置src打开office文件。
-
- DLL等组件调用
主要有三种方法来实现。
- 通过打开IE内核,来createObject调用ActiveX ,一般调用ActiveX需要已经注册
- JS控制AppEmit调用DLL接口,互动信息,有些ActiveX可以免注册。
可以调用标准的COM组件、ActiveX以及DLL,支持可视化ocx,同时可以开发互动的dll,能在浏览器中控制调用的组件或者程序。
APP |
嵌入网页JS |
浏览器网页 |
AppEmit |
-
-
- 使用IE内核打开ActiveX
-
使用IE内核打开网页,在非IE浏览器中调用activeX控件,及使用原有的html的代码即可。
{"emit":"open","Obj":"web","AppType":1,"pos":1,"par":{"htmlStr":null,"HttpServer_startUrl":null,"URL":"http://www.baidu"},"par0":{"header":null,"noScriptErr":true, "UIFLAG":null,"DLCTL":null,"userAgent":null,"crossDomain":true}}
设置htmlStr可以直接打开html源码。
设置HttpServer_startUrl,可以打开本地的html文件。
设置URL打开网页。 三者优先级依次下降。
同时也能通过浏览器网页发布命令。
-
-
- JS控制AppEmit调用可视化com组件
-
- Flash ocx 调用,能在网页中执行命令,控制flash,举例见demo/htmlDemo/dll.html
{"emit":"open","Obj":"dll","AppType":1,"src":[],"pos":1,"par":{"htmlStr":null,"HttpServer_startUrl":null,"URL":"/demo/htmlDemo/js/dllJs.html","webJs":1}
调用C:/Windows/SysWOW64/Macromed/Flash/Flash32_32_0_0_403.ocx 控件,需要自行安装flash.
可以在dllJs.html进一步设置参数AppType==1情况,和过程调用代码。
同时也能通过浏览器网页发布命令。
- 第三方控件ReportX.ocx,联系AppEmit检查安全性后配置在/plugins/thirdparty目录中,直接调用
报表控件reportX调用。
能在网页中执行命令,控制reportX,举例见demo/htmlDemo/dll.html
{"emit":"open","Obj":"dll","AppType":2,"src":[],"pos":1,"par":{"htmlStr":null,"HttpServer_startUrl":null,"URL":"/demo/htmlDemo/js/dllJs.html","webJs":1},"par0":{"AppMethod":"msg Synchronization component need set: POST" }}
调用"/plugins/thirdparty/report/ReportX.ocx" 控件
可以在dllJs.html进一步设置参数AppType==2情况,和过程调用代码。
同时也能通过浏览器网页发布命令。
-
-
- JS控制AppEmit调用第三方Dll
-
- dll 调用,第三方控件,联系AppEmit检查安全性后配置在/plugins/thirdparty目录中,直接调用,能在网页中执行命令,举例见demo/htmlDemo/dll.html
{"emit":"open","Obj":"dll","AppType":4,"src":[],"AppShow":false,"par":{"htmlStr":null,"HttpServer_startUrl":null,"URL":"/demo/htmlDemo/js/dllJs.html","webJs":1 },"par0":{"AppMethod":"msg Synchronization component need set: POST" }}
可以在dllJs.html进一步设置参数AppType==4情况,和过程调用代码,演示调用add方法。
同时也能通过浏览器网页发布命令。
-
- Dll开发
可以通过2种方法来实现
- 开发的DLL可以和AppEmit保持接口一致,完成通信调用。
- 注册开发的DLL,在非IE浏览器打开IE内核来调用,见web IE内核章节。
下面介绍第一种方法,自有开发的私人DLL或者组件,需要申请Pid后开发dll,安装在/plugins/private/目录下,需要双方验证成功后才能调用
参考demo/htmlDemo/dll/dll_demo1.c,提供了接口规范。 使用最新版本TCC开发的dll。
调用dll_demo1.dll,能在嵌入网页中执行命令,控制dll_demo1,举例见demo/htmlDemo/dll.html
{"emit":"open","Obj":"dll","AppType":3,"src":[],"AppShow":false,"par":{"htmlStr":null,"HttpServer_startUrl":null,"URL":"/demo/htmlDemo/js/dllJs.html","webJs":1 },"par0":{"AppMethod":"msg Synchronization component need set: POST" }}
调用/plugins/private/50FCF891-1B93-4AE5-8A66-AB26A3C03378/dll_demo1.dll
可以在dllJs.html进一步设置参数AppType==3情况,和过程调用代码。
同时也能通过浏览器网页发布命令runCmd。
-
- 插件部署
在发布时,也可以把此AppEmit插件目录文件和AppEmit.exe一起打包后发布,不用单独分发。
名称 |
路径 |
作用 |
blink |
/plugins/lib/web/blink/.dll/node.dll |
浏览器内核 |
/plugins/lib/web/blink/.dll/wkex.dll |
||
flash_NP |
/plugins/NPSWF32.dll" |
NP版本flash |
/plugins/plugin.vch |
||
aliplayer |
/plugins/common/aliplayer |
Aliplayer播放器支持 视频格式:mp4、flv、m3u8、rtmp 视频编码:H.264 音频编码:AAC、MP3 音频格式:MP3 |
|
/plugins/common/pdfjs |
浏览PDF文件 |
- Dll开发
-
- 开发
-
自有开发的私人DLL或者组件,需要申请Pid (pid>=guid=clsId)可使用GUID工具自行生成后开发dll,安装在/plugins/private/目录下,需要双方验证成功后才能调用
参考demo/htmlDemo/dll/dll_demo1.c,提供了接口规范。 使用最新版本TCC开发的dll。
主要是5个函数接口,App开头的函数和变量名称不要改变
AppDll_init dll初始化,用户输入参数 认证
AppDll_loaded dll启动后执行
AppDll_destroy dll 退出前执行
AppDll_RevMsg 互动时 接收 消息
AppDll_SendMsg 互动时 反馈 消息
模板如下,使用了cJSON开源库。
#include <windows.h>
// #include <string.h>
#include "cJSON.h" 需要下载开源库cJSON
#include "cJSON.c"
// 开发可以互动信息的动态链接库 Dll
// http://www.appemit
生成DLL 必须使用最新版tcc扩展库才能支持UTF8,UTF16字符串
/*
入口函数,该函数可以有也可以没有。
入口函数会自动加锁以保证线性调用,要避免在DllMain内调用下列函数:
1、调用LoadLibrary或其他可能加载DLL的API函数( CreateProcess等 )
2、可能再次触发DllMain的函数,例如 CreateThread,ExitThread
3、GetModuleFileName, GetModuleHandle 等其他可能触发系统锁的API函数
总之在DllMain最好不要调用API函数.
*/
/*
主要是5个函数接口,App开头的函数和变量名称不要改变
AppDll_init dll初始化,用户输入参数 认证
AppDll_loaded dll启动后执行
AppDll_destroy dll 退出前执行
AppDll_RevMsg 互动时 接收 消息
AppDll_SendMsg 互动时 反馈 消息
*/
char *mycid ="00000-1"; //申请的公司产品cid ,需要修改
char *clsId="50FCF891-1B93-4AE5-8A66-AB26A3C03378"; // pid>=guid=clsId 可使用GUID工具自行生成
int dllThid; //本进程ID
// sid; //websocket里面设置的,一般为用户ID或者sessionID,唯一
// rid ; //第rid次调用
int AppAuth=0; //
//测试
char* joinStr(char *s1, char *s2, char *s3)
{
char *result = malloc(strlen(s1)+strlen(s2)+strlen(s3)+1);//+1 for the zero-terminator
if (result == NULL) exit (1);
strcpy(result, s1);
strcat(result, s2);
strcat(result, s3);
return result;
}
int __stdcall DllMain(void * hinstDLL, unsigned long fdwReason, void * lpvReserved) {
if (fdwReason == 1/*DLL_PROCESS_ATTACH*/ ){
}
return 1;
}
//__declspec(dllexport) 声明导出函数
__declspec(dllexport) int AppDll_RevMsg(HWND hwnd, char *ids,char *msg)
{
AppDll_SendMsg(hwnd,ids,msg);
return 0;
}
__declspec(dllexport) int AppDll_SendMsg(HWND hwnd, char *ids,char *msg)
{
//检查是否有 clsId
cJSON * ids_json= cJSON_Parse(ids);
if (!ids_json) {ids_json=cJSON_CreateObject();}
if (!cJSON_GetObjectItem(ids_json,"clsId")) {
cJSON_AddStringToObject(ids_json, "clsId", clsId); //必需字段
}
ids=cJSON_PrintUnformatted(ids_json);
cJSON_Delete(ids_json);
struct {char * ids;char * msg; } callBackMsg = {
.ids=ids,
.msg =msg, // 只会反馈msg里面data字段到websocket
};
SendMessage(
hwnd,0xACCE ,
"AppOnMsg({string ids;string msg;})", //要调用的窗体函数名( 结构体原型声明 ); 结构体原型声明应使用API语法
&callBackMsg //将前面定义的结构体作为调用参数
);
return 0;
/*
0xACCE=_WM_THREAD_CALLBACK 使所有回调安全的转发到UI线程。
_WM_THREAD_CALLBACK 可以跨线程跨语言并且不需要创建回调线程,适用任何普通winform对象。
*/
}
__declspec(dllexport) int AppDll_init(HWND hwnd, char *ids,char *msg)
{
//判断获得AppEmit提供ids(格式json)里面cid sid pid AuthKey等数据
//和websocket的自行web提供的Json里面的data,判断验证来源是否正确
// ids ="{\"cid\":\"00000-1\",\"sid\":\"f1s\",\"rid\":2333,\"AuthKey\":\"000\",\"clsId\":\"50FCF891-1B93-4AE5-8A66-AB26A3C03378\"}";
//具体数据和判断需要修改
cJSON * ids_json= cJSON_Parse(ids);
// char * ids3= cJSON_PrintUnformatted(ids_json); //如果解析报错尝试使用cJSON
// cJSON * ids_json2= cJSON_Parse(ids3);
if (!cJSON_GetObjectItem(ids_json,"clsId") || !cJSON_GetObjectItem(ids_json,"cid") || !cJSON_GetObjectItem(ids_json,"AuthKey")) { cJSON_Delete(ids_json);return -1;}
dllThid = GetCurrentThreadId();
cJSON_AddNumberToObject(ids_json, "dllThid", dllThid); //必需
cJSON_AddStringToObject(ids_json, "more", NULL); //备用字段
//必须反馈验证
if (strcmp(cJSON_GetObjectItem(ids_json,"cid")->valuestring,mycid)==0 && strcmp(cJSON_GetObjectItem(ids_json,"AuthKey")->valuestring,"000")==0 && strcmp(cJSON_GetObjectItem(ids_json,"clsId")->valuestring,clsId)==0) {
//msg若反馈必须有 \"clsId\" \"AppAuth\"。AppAuth为1 clsId一致 才继续 // 支持\" 或者 '
msg = joinStr("{\"data\":{\"code\":200,\"cid\":\"00000-1\",\"sid\":\"123\",\"rid\":-1,\"rec\":",msg,",\"AppStep\":\"init\"}}");
cJSON_AddNumberToObject(ids_json, "AppAuth", 1);
char *ids2=cJSON_PrintUnformatted(ids_json);
//必须反馈验证
AppDll_SendMsg(hwnd,ids2,msg);
}else{
cJSON_AddNumberToObject(ids_json, "AppAuth", 0);
char *ids2=cJSON_PrintUnformatted(ids_json);
// 反馈验证
AppDll_SendMsg(hwnd,ids2,NULL);
}
cJSON_Delete(ids_json);
return 0;
}
__declspec(dllexport) int AppDll_loaded(HWND hwnd, char *ids,char *msg)
{
//处理业务 //msg若反馈必须有data
// msg = joinStr("{\"data\":{\"code\":200,\"cid\":\"00000-1\",\"sid\":\"123\",\"rid\":-1,\"rec\":",msg,",\"AppStep\":\"loaded\"}}");
//若反馈则
AppDll_SendMsg(hwnd,ids,msg); //如果msg中没有data,则不反馈到浏览器中
return 0;
}
__declspec(dllexport) int AppDll_destroy(HWND hwnd, char *ids,char *msg)
{
//处理业务msg若反馈必须有 data
//msg = joinStr("{\"data\":{\"code\":200,\"cid\":\"00000-1\",\"sid\":\"123\",\"rid\":-1,\"rec\":",msg,",\"AppStep\":\"destroy\"}}");
//若反馈则
AppDll_SendMsg(hwnd,ids,msg);
return 0;
}
//测试
__declspec(dllexport) int Add(int a, int b )
{
return a+b;
}
__declspec(dllexport) int AppDll_init(HWND hwnd, char *ids,char *Json)
{
//判断获得AppEmit提供ids(格式json)里面cid sid pid Auth等数据
//和websocket的自行web提供的Json里面的data,判断验证来源是否正确
//msg若反馈必须有 \"AppStep\", \"clsId\" \"AppAuth\"。AppAuth为true clsId一致 才继续
// 支持\" 或者 ' 如果有data,只发送data字段到浏览器websock接收
char *msg = joinStr(joinStr("{\"data\":{\"code\":200,\"cid\":\"00000-1\",\"sid\":\"123\",\"rid\":-1,\"rec\":",Json,",\"AppStep\":\"init\"},\"AppStep\":\"init\",\"AppAuth\":true,\"clsId\":\""),clsId,"\"}");
dllThid = GetCurrentThreadId();
//必须反馈验证
AppDll_OnMsg(hwnd,ids,msg);
return 0;
}
__declspec(dllexport) int AppDll_loaded(HWND hwnd, char *ids,char *Json)
{
//处理业务 //msg若反馈必须有 \"clsId\".如果有data,只发送data到浏览器websock接收
char *msg = joinStr(joinStr("{\"data\":{\"code\":200,\"cid\":\"00000-1\",\"sid\":\"123\",\"rid\":-1,\"rec\":",Json,",\"AppStep\":\"loaded\"},\"AppStep\":\"loaded\",\"clsId\":\""),clsId,"\"}");
//若反馈则OnMsg
AppDll_OnMsg(hwnd,ids,msg);
return 0;
}
__declspec(dllexport) int AppDll_destroy(HWND hwnd, char *ids,char *Json)
{
//处理业务msg若反馈必须有 \"clsId\" .如果有data,只发送data到浏览器websock接收
char *msg = joinStr(joinStr("{\"data\":{\"code\":200,\"cid\":\"00000-1\",\"sid\":\"123\",\"rid\":-1,\"rec\":",Json,",\"AppStep\":\"destroy\"},\"AppStep\":\"destroy\",\"clsId\":\""),clsId,"\"}");
//若反馈则OnMsg
AppDll_OnMsg(hwnd,ids,msg);
return 0;
}
//测试
__declspec(dllexport) int Add(int a, int b )
{
return a+b;
}
-
-
- 调用
-
主要有两种方法来实现。
- 通过AppEmit来调用DLL互动信息,有些ActiveX可以免注册。
- 通过打开IE内核,来createObject调用ActiveX ,需要注册ActiveX
下面使用AppEmit来调用DLL互动信息
- 生成dll_demodll后,安装在/plugins/private/Pid/下面
/plugins/private/50FCF891-1B93-4AE5-8A66-AB26A3C03378/dll_demo1.dll"
就能在能在网页中执行命令,调用互动dll_demo1,举例见demo/htmlDemo/dll.html
{"emit":"open","Obj":"dll","AppType":3,"src":[],"AppShow":false,"par":{"htmlStr":null,"HttpServer_startUrl":null,"URL":"/demo/htmlDemo/js/dllJs.html","webJs":1 },"par0":{"AppMethod":"msg Synchronization component need set: POST" }}
可以在dllJs.html进一步设置参数AppType==3情况,在dllJs.html中也可以设置src参数和过程,调用代码。
同时也能通过浏览器网页发布命令runCmd,执行AppDll_RevMsg方法。
codeStr= txt2code(function(){/*
AppJsObject.dll_demo1.AppDll_RevMsg(AppDll_hwnd,'','{"data":"send from JS","info":3}');
* /});
var Req={"emit":"runCmd","Obj":"dll","codeStr":codeStr }
EmitReq(Req);
-
-
-
- 嵌入网页JS控制
-
-
- AppJs_init=function(AppType)
如果在浏览器网页中没有设置src,可以在这里设置。
src:[ {
// webJs0:0, //只能设置为0 关闭本js的控制 ; 或者注释 为默认打开控制
createType:"createDll" // dll调用
,objName:"dll_demo1"
,dllFile:"/plugins/private/50FCF891-1B93-4AE5-8A66-AB26A3C03378/dll_demo1.dll" // 必须 \\ / 放在/plugins/private/clsId/文件夹下面
,clsId :"50FCF891-1B93-4AE5-8A66-AB26A3C03378" //guid 发送给dll 信息
,iid:null
,data:'{"msg":"init from JS","info":1}' //发送给dll 数据
} //暂时支持一个控件
]
,AppShow:false //整体不可见 必须设置,默认可见
- AppJs_loaded=function(AppType){
//系统启动APP ,产生AppJsObject. shockwave对象后执行
- AppJsObject.dll_demo1.AppDll_loaded(AppDll_hwnd, "",{"msg":"loaded from JS","info":2}');
- AppJs_destroy=function(){ //AppJsObject.shockwave销毁前执行
AppJsObject.dll_demo1.AppDll_destroy(AppDll_hwnd, "",{"msg":"destroy from JS","info":3}');
- AppJs_closed=function(status){ //AppJsObject.shockwave关闭后执行。已经没有AppJsObject.shockwave对象了
-
-
-
- 浏览器网页执行代码命令控制
-
-
AppJsObject.dll_demo1
Var Req={"emit":"runCmd","Obj":"dll","codeStr": codeStr}
EmitReq(Req);
通过前面dllJs.html定义的AppJsObject.dll_demo1,可以直接控制dll_demo1。当然也可以不需要dllJs.html定义,能在浏览器网页中websocket发送使用"emit":"runCmd"命令发送AppJs_init、AppJs_loaded,代码也可以。
- 参数
- 连接
ws://localhost:80/appemit?cid=00000-1&sid=1&flag=1
名称 |
设置 |
含义 |
说明 |
协议 |
ws |
SSL为wss |
|
网址 |
Localhost 127.0.0.1 |
||
port |
[80,8617,8618,8619,9780] |
数值或者数组,默认80。 |
依次尝试打开端口。若所有端口被占用 尝试关闭最后一个port的进程,打开最后一个端口 都可以在config.in修改 |
[443,5124,5125,5126,43100] |
ssl默认443。 |
同上。 |
|
path |
appemit |
必需 |
|
para |
cid |
必需。00000-1为免费账号。 |
全集。 |
sid |
字符串,通常情况可选。唯一session或者用户名ID |
测试后最好在js中实现隐藏。如果需要调用私有APP,则必须有,否则无法互相通话。 |
|
flag |
可选。默认0,非调试。 1调试 |
-
- 初始化数据
{"emit":"init",…}
var AE_initSet = {
"emit":"init",
"clientKey": "temp-0000000000", //
"clientInfo":clientInfo,
"wsUrl": wsUrl,
// "flag":0,
// "sid":"123456", // 用户session 或者用户名ID,唯一可以准确通话
"gid": "[1,2]", //用户群ID,一个用户可以加入多个群
// "utf_escape":false, //默认false, 反馈的data编码转义
};
名称 |
设置 |
含义 |
说明 |
emit |
init |
必需。初始化请求。 |
|
clientKey |
temp-0000000000 |
必需, 客户端,与cid对应。 |
保密,js应该混淆加密。 |
clientInfo |
对象 |
必需。使用浏览器。 默认 |
|
wsUrl |
wsUrl |
必需。默认 |
可以在config.in修改 |
sid |
字母数字下划线短线 |
必需。用户或者session,唯一才可以正常通话。 |
生产环境,同一设置于此。 |
gid |
数组 |
非必需。 群 |
一个sid可有不同gid |
utf_escape |
false |
默认false |
反馈的data编码转义 |
-
- 命令
说明,参数分组为{a,par:{b},par0:{c}}
abc里面的字段名称都要不同。
参数形式如下
名称 |
设置 |
含义 |
说明 |
|
emit |
init 初始化 open 打开App runCmd 互动调用App运行命令 close|closeAll 关闭App msg 发送消息 hardware 获取硬件信息 |
|||
Obj |
pc |
|||
AppId |
1 |
1,2,3 |
一个页面一个APP,默认为1。 |
|
AppType |
1,-1 |
1,2,3,4… -1,-2,-3,-4 |
正数嵌入 负数浮动 |
|
pos |
1,-1 [left,top,width,height] |
位置 1 更新位置 -1 删除位置数据 [left,top,width,height] 保留 |
||
data |
||||
src |
||||
AppShow |
必需。 true App可见 false App不可见 |
通常空时默认为true 调用comm为false |
||
AppFollow |
必需。空时默认为true 1 跟随变化 0 不变化 |
AppShow为true时,App随浏览器移动变形隐藏显示等事件 |
||
AppStatus |
1/0 |
系统自动反馈 0关闭 |
接收的数据 |
|
版权声明:本文标题:AppEmit是应用程序(尤其是浏览器)与本地程序间互相通信的易扩展的轻量级中间件 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/dongtai/1726397401a1068928.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论