AAUTO是一个国产小众语言,和lua算是近亲,官方网站 www.aau.cn

使用aauto的优点我认为对于我来说最主要的有以下两点:

1.无需臃肿的框架类似.NET FRAMEWORK、Adobe AIR等便可开发出小巧而实用的windows程序

2.支持HTMLLAYOUT,对于原来熟悉html+css的web开发者来说是个福音,降低了学习成本

废话不多说了,下面开始介绍下我使用aauto这个短小精悍的语言所开发的访问使用CloudStack所创建的虚拟机的云桌面访问客户端。

界面演示

实现功能

该客户端在输入用户名密码验证登录成功后

1.屏蔽了windows,ALT+F4 以禁止用户返回原生桌面或关闭当前程序(其实屏蔽ALT+F4)

架构详解

下图是该项目的全部文件目录树。

该客户端仅有一个主窗体文件main.aau,界面演示图中的效果是有layout中的index.html实现。sys.ini中配置保存的用户名及登录验证服务网址.

代码详解

main.aau中核心代码如下:

import win.ui;
import win.ui.menu;
import win.ui.atom;
import win.timer;
import inet.whttp;
import web.layout;
import web.layout.behavior.windowCommand;
import fsys.ini;
import sys;
import win.reg;
import key;
import crypt.des;
import crypt.bin;

_ver = "1.1.0 build 20141017"
//常量定义
_APP_NAME="clouddesktop"

mainForm = win.form(text="云桌面登录客户端";right=0;bottom=0;border="none";max=false;min=false;maxmize=1)

var debug =(_STUDIO_INVOKED ? true:false)
var des = crypt.des();
des.setPassword("huiyou");
if(!debug){
win.setTopmost(mainForm.hwnd)
}
/*------------------ 公用函数 -------------------*/
function decrypt(str){
var rtn = crypt.bin.decodeBase64(str);
return des.decrypt(rtn);
}

function encrypt(str) {
var rtn = des.encrypt(str);
return crypt.bin.encodeBase64(rtn);
}
/*------------------ 公用函数 END -------------------*/
//win.setTopmost(mainForm.hwnd)

var atom,hwnd/*冲突窗口的句柄,该函数会自动激活此窗口*/ = mainForm.atom("BB84EAAE-004C-4AF7-8087-98550285C32E");
if(!atom){
/*为窗口设置原子值可以避免一个程序重复运行多个实例*/
win.quitMessage();
return;
}

var ini = fsys.ini("/sys.ini")

//1.禁用任务管理器
var reg = win.reg("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\System")
reg.setDwValue("DisableTaskMgr",1)

var binpath = io._exepath;
var displayname = "云桌面客户端"
var description = "云桌面客户端"
/*自动启动*/
reg = win.reg("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run")
reg.setSzValue(_APP_NAME, binpath)
//reg.delKeyTree("HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Run\clouddesktop")
//禁用运行
reg = win.reg("HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Policies\Explorer")
reg.setDwValue("DisallowRun",1)

wbLayout = web.layout(mainForm)
//禁止窗体绘制默认背景,避免不必要的闪烁
mainForm.onEraseBkgnd = function(hwnd,message,wParam,lParam){
return 0;
}

wbLayout.go("/layout/index.html");
//----------------屏蔽按键

import key.hook;
hk = key.hook()

hk.proc = function(msg,vkcode,scancode,injected,flags,timeStamp,extraInfo){
if( injected ) return;
var kn = key.getName( vkcode );
select(msg) {
case 0x100/*_WM_KEYDOWN*/ ,0x104/*_WM_SYSKEYDOWN*/{
if(kn=="LWIN" || kn=="RWIN"
|| ((flags & 0x20/*_LLKHF_ALTDOWN*/)!=0 && kn=="F4")
)
{
return true
}
elseif( kn == "0" && key.getStateX("CTRL")){
reg.close();win.quitMessage();
}
}
}
}

//----------------屏蔽按键END
timer=win.timer( mainForm);
quit = function(){hk.close();timer.disable();reg.close();win.quitMessage();}

_section_AutoLogin="autologin"
var isAutoLogin=false;
if(ini.readKeys(_section_AutoLogin)){
sec = ini.getSection(_section_AutoLogin)
rememberUserName=sec.rememberUserName//记住用户名
//autoLogin=sec.autoLogin
}

if(rememberUserName=="1"){
wbLayout.getEle("cbxRemember").value=true
wbLayout.getEle("username").value= decrypt(sec.userName)
}
/*
if(autoLogin=="1"){
isAutoLogin=true;
wbLayout.getEle("userpass").value = sec.userPass;
wbLayout.getEle("cbxAutoLogin").value = true
wbLayout.getEle("btnSmt").click()
}
*/

var http = inet.whttp();
//请求服务baseurl,可用用户名
var serverBaseUrl=ini.read("server","url","http://140.28.22.122:8080/admin/getvm");
if(false == string.startWith(serverBaseUrl,"http://")){
serverBaseUrl = decrypt(serverBaseUrl);
}
wbLayout.onButtonClick = function (ltTarget,ltEle,reason,behaviorParams) {
if( ltEle.id == "btnSmt"){
var username=wbLayout.getEle("username").value;
var password=wbLayout.getEle("password").value;
rememberUserName=wbLayout.getEle("cbxRemember").value;
//autoLogin=wbLayout.getEle("cbxAutoLogin").value;

if(username=="用户名")username="t1"
if(!#password || password=="密码")password="t1"
if(!#username){mainForm.msgbox("请输入用户名")return;}
if(!#password){mainForm.msgbox("请输入密码")return;}

var url=string.concat(serverBaseUrl,"?command=getsvm&username=",username,"&password=",password);
var str;
try{str = http.get(url)}
catch(e){mainForm.msgbox("无法连接到远程服务,请检查远程服务是否可访问");return;}

if( null ==str || !#str){mainForm.msgbox("登录失败,请检查网络连接情况并稍后再试");return}
if(str=="1"){mainForm.msgbox("登录失败,请检查用户名密码是否正确");return}

//------------ 保存用户名密码等到配置文件
/*保存用户名密码等到配置文件{{*/
ini.write(_section_AutoLogin,"rememberUserName",rememberUserName?1:0)
//ini.write(_section_AutoLogin,"autoLogin",autoLogin?1:0)
if(rememberUserName){
var sUserName = des.encrypt(username);
ini.write(_section_AutoLogin,"userName",crypt.bin.encodeBase64(sUserName));
}
/*
if(autoLogin){
ini.write(_section_AutoLogin,"userPass",password)
}
*/
/*}}*/
//------------ 保存用户名密码等到配置文件 END

if(isAutoLogin){
ltEle.value="登陆中...";
}
var arr= string.split(str,'$')
userid=arr[1];
var serverip=arr[2];
var port = arr[3];
var vmUserName=arr[4];
var vmpwd = arr[5];
var desktopUrl=arr[6];

//-------------- 远程连接start
import com.lite;
rdpClient = com.lite("MsTscAx.dll").createEmbed(mainForm,"{7cacbd7b-0d99-468f-ac33-22e495c0afe5}")
msTscAx = rdpClient._object;//获取控件对象

//响应远程桌面事件
rdpClient.OnDisconnected = function(discReason){
//mainForm.msgbox(discReason)
select (discReason) {
case 1,2{
quit();
if(!debug)sys.shutdown();
}
}
}

//设置远程登录参数
msTscAx.Server = serverip;
msTscAx.UserName = vmUserName;
msTscAx.AdvancedSettings2.ClearTextPassword = vmpwd;
msTscAx.AdvancedSettings2.RDPPort = port; //端口
msTscAx.AdvancedSettings2.RedirectPrinters = true; //共享打印
msTscAx.AdvancedSettings2.RedirectDrives = true; //允许共享磁盘
msTscAx.AdvancedSettings2.RedirectDynamicDrives =true;
msTscAx.AdvancedSettings2.SmartSizing = true; //自动调整大小
msTscAx.AdvancedSettings2.DisplayConnectionBar=true;
msTscAx.AdvancedSettings2.DisableCtrlAltDel = 1;
msTscAx.AdvancedSettings2.EnableWindowsKey = 0;
//msTscAx.AdvancedSettings.Compress=1;
//msTscAx.AdvancedSettings.BitmapPeristence = 1;// 将位图缓存到磁盘
//msTscAx.SecuredSettings2.StartProgram = "c:\browser.exe "++ desktopUrl;
msTscAx.FullScreen = false;//是否全
msTscAx.FullScreenTitle = mainForm.text;//全屏标题
msTscAx.ColorDepth = 32;//32位颜色
msTscAx.ConnectingText = "欢迎使用云桌面,正在连接,请稍候......"
msTscAx.Connect(); //连接

//-------------- 远程连接 END

//加载计时器
timer.enable();
timer.setInterval(120000)//2分钟发送一次heartbeat
}
}

var elePwd = wbLayout.getEle("userpass")
elePwd.onKeyUp = function( ltTarget,ltOwner,keyCode, altState, ltKeyParams ) {
if(ltOwner.id == "userpass" && keyCode==13){wbLayout.getEle("btnSmt").click()}
}
elePwd.attachEventHandler()

//发送heartbeat
timer.onTimer = function(hwnd,msg,id,tick){
if(!userid || !#userid) return;
var url=string.concat(serverBaseUrl,"?command=heartbeat&userid=",userid);
http.get(url);
}

mainForm.onClose = function(hwnd,message,wParam,lParam){
return false;
if(#userid){
var url=string.concat(serverBaseUrl,"?command=logout&userid=",userid);
http.get(url);
http.close()
}
process.kill("mstsc.exe")
quit();
collectgarbage("collect");//内存回收,确保完全退出
if(!debug)sys.shutdown();
}

//响应窗口事件
mainForm.wndproc = function(hwnd, message,wparam,lparam){
select(message) {//判断消息类型
case 0x10/*_WM_CLOSE*/{
return true;//阻止关闭
};
case 0x282
{
import winex;
var winHwnd,ch,tid,pid = winex.findExists("<云桌面登录客户端>","","<AAU_FORM[\S+]>","<ATL:\w+>")
if(ch!=null){
rdpClient._host.doObjectVerb( -5)
}
};
}
}//endproc

mainForm.show()
//import cloudDesktop.common;
//cloudDesktop.common.checkUpdate();
win.loopMessage();

sys.ini中内容

[autologin]
userName=7JB75wW03kA=
rememberUserName=1

[server]
url=http://xxxxxx/admin/getvm

使用AAUTO语言开发的云桌面登录客户端的更多相关文章

  1. 基于Hadoop开发网络云盘系统客户端界面设计初稿

    基于Hadoop开发网络云盘系统客户端界面设计初稿 前言: 本文是<基于Hadoop开发网络云盘系统架构设计方案>的第二篇,针对界面原型原本考虑有两个方案:1.类windows模式,文件夹 ...

  2. 开源前夕先给大家欣赏一下我用C语言开发的云贴吧 网站自动兼容-移动、手机、PC自动兼容云贴吧

    开源前夕先给大家欣赏一下我用C语言开发的移动.手机.PC自动兼容云贴吧 - 涨知识属马超懒散,属虎太倔强.十二生肖全了!-转自云寻觅贴吧 转: 涨知识属马超懒散,属虎太倔强.十二生肖全了! -转自云寻 ...

  3. 开源前夕先给大家赞赏一下我用C语言开发的云贴吧 站点自己主动兼容-移动、手机、PC自己主动兼容云贴吧

    开源前夕先给大家赞赏一下我用C语言开发的移动.手机.PC自己主动兼容云贴吧 - 涨知识属马超懒散,属虎太倔强.十二生肖全了!-转自云寻觅贴吧 转: 涨知识属马超懒散,属虎太倔强.十二生肖全了! -转自 ...

  4. OpenStack虚拟云桌面在携程呼叫中心的应用

    编者:本文为刘科在第六期[携程技术微分享]中的分享内容.在携程技术中心(微信号ctriptech)微信后台回复[云桌面],可加入微信交流群,和关注云桌面的小伙伴一起玩耍~ 刘科,携程系统研发云平台桌面 ...

  5. 黄聪:远程序桌面登录的.NET(C#)开发

    MSTSCLib.dll和MsTscAxWrapper.dll下载:LibDll.rar 远程序桌面登录的.NET开发,可以使用MSTSCLib.dll和MsTscAxWrapper.dll两个转换过 ...

  6. 【Linux 操作系统】阿里云服务器 操作实战 部署C语言开发环境(vim配置,gcc) 部署J2EE网站(jdk,tomcat)

    . 作者 :万境绝尘  转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/18964835 . 博客总结 : 设置SecureCRT ...

  7. 阿里云服务器 操作实战 部署C语言开发环境(vim配置,gcc) 部署J2EE网站(jdk,tomcat)

    . 作者 :万境绝尘  转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/18964835 . 博客总结 : 设置SecureCRT ...

  8. Go语言开发环境配置

    一.我为什么要学习go语言 当今已经是移动和云计算时代,Go出现在了工业向云计算转型的时刻,简单.高效.内 置并发原语和现代的标准库让Go语言尤其适合云端软件开发(毕竟它就是为此而设计的).到2014 ...

  9. (转载)Go语言开发环境配置

    一.我为什么要学习go语言 当今已经是移动和云计算时代,Go出现在了工业向云计算转型的时刻,简单.高效.内 置并发原语和现代的标准库让Go语言尤其适合云端软件开发(毕竟它就是为此而设计的).到2014 ...

随机推荐

  1. POJ 2177 Ghost Busters(三维几何)

    Description The famous Ghost Busters team has decided to upgrade their Ectomobile (aka Ecto-1) with ...

  2. js单行写一个评级组件

    单行写一个评级组件:"★★★★★☆☆☆☆☆".slice(5 - rate, 10 - rate); -----------------------------------分隔符- ...

  3. Thunder团队第五周 - Scrum会议4

    Scrum会议4 小组名称:Thunder 项目名称:i阅app Scrum Master:李传康 工作照片: 邹双黛同学在拍照,所以不在照片内. 参会成员: 王航:http://www.cnblog ...

  4. Thunder团队第二周 - Scrum会议5

    Scrum会议5 小组名称:Thunder 项目名称:爱阅app Scrum Master:苗威 工作照片: 参会成员: 王航:http://www.cnblogs.com/wangh013/ 李传康 ...

  5. php中array_map和array_walk的使用对比

    一.array_map() 1.array_map() 函数将用户自定义函数作用到数组中的每个值上,并返回用户自定义函数作用后的带有新值的数组,若函数作用后无返回值,则对应的新值数组中为空. 2.回调 ...

  6. 团队作业7——第二次项目冲刺(Beta版本)-第一篇

    1.当天站立式会议照片: 2.工作分工: 团队成员 分工 郭达22120 项目整合,后台代码 刘德培44060 数据库模块后台连接 石浩洋22061 前台界面优化 曾繁钦22056 前台界面优化.测试 ...

  7. <Effective C++>读书摘要--Resource Management<二>

    <Item 15> Provide access to raw resources in resource-managing classes 1.You need a way to con ...

  8. android gradle打包常见问题及解决方案

    背景: 问题: Q1: UNEXPECTED TOP-LEVEL ERROR: java.lang.OutOfMemoryError: Java heap space at com.android.d ...

  9. Redis的概述和简单使用(转载)

    文章来源:http://jingyan.baidu.com/article/db55b60996d0124ba30a2f92.html Redis是一个基于key-value的高速缓存系统,类似于me ...

  10. SpringBoot JDBC/AOP

    JDBC 工程结构: pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmln ...