使用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_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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM