• 使用AAUTO语言开发的云桌面登录客户端


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

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

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

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

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

    界面演示

    image

    实现功能

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

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

    架构详解

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

    image

    该客户端仅有一个主窗体文件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_USERSoftwareMicrosoftWindowsCurrentVersionPoliciesSystem")
    reg.setDwValue("DisableTaskMgr",1)

    var binpath = io._exepath;
    var displayname = "云桌面客户端"
    var description = "云桌面客户端"
    /*自动启动*/
    reg = win.reg("HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersionRun")
    reg.setSzValue(_APP_NAME, binpath)
    //reg.delKeyTree("HKEY_LOCAL_MACHINESoftwareMicrosoftWindowsCurrentVersionRunclouddesktop")
    //禁用运行
    reg = win.reg("HKEY_CURRENT_USERSoftwareMicrosoftWindowsCurrentVersionPoliciesExplorer")
    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:rowser.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

  • 相关阅读:
    关于Java中System.currentTimeMillis和System.nanoTime的错误认识
    多线程以外
    vim 小技巧
    Virtual Box HostOnly网络模式配置
    How 30 Minutes a Day Can Increase Your Intelligence
    YUM命令使用
    Hash算法及其应用
    jetty + apache httpd 反向代理配置
    使用SCTP优化网络
    .NET书籍推荐
  • 原文地址:https://www.cnblogs.com/s1ihome/p/4099496.html
Copyright © 2020-2023  润新知