air 开放记录
这两天做了air版的game外壳
主要功能是获取硬盘序列号和mac地址还有自动更新
先说mac地址获取:
这个很简单,air它本身就支持
方法是
1 //网络信息 2 if (NetworkInfo.isSupported) { 3 var info:NetworkInfo=NetworkInfo.networkInfo; 4 var infofaceVec:Vector.<NetworkInterface>=info.findInterfaces(); 5 //mac地址-------------------------------------ip地址 6 param.push(infofaceVec[0].hardwareAddress, infofaceVec[0].addresses[0].address); 7 }
再说硬盘序列号获取:
这个获取是用第三方文件vb获取,然后air调用的
具体方法:
1 package com.cn.desk { 2 import flash.desktop.NativeApplication; 3 import flash.desktop.NativeProcess; 4 import flash.desktop.NativeProcessStartupInfo; 5 import flash.events.IOErrorEvent; 6 import flash.events.ProgressEvent; 7 import flash.filesystem.File; 8 import flash.filesystem.FileMode; 9 import flash.filesystem.FileStream; 10 import flash.text.TextField; 11 import flash.utils.IDataInput; 12 13 public class DeskSerialNumber { 14 private var nativeProcess:NativeProcess; 15 private var tmpfile:File; 16 private var param:Array=[]; 17 18 public function DeskSerialNumber(param:Array) { 19 this.param=param; 20 this.init(); 21 } 22 23 private function init():void { 24 25 tmpfile=File.userDirectory 26 27 this.buildToVbs(); 28 29 //return ; 30 var args:Vector.<String>=new Vector.<String>(); 31 args.push("/c cscript " + tmpfile.resolvePath("e.vbs").nativePath); 32 33 //NativeApplication.nativeApplication.autoExit=false; 34 var nativstart:NativeProcessStartupInfo=new NativeProcessStartupInfo(); 35 //nativstart.executable=new File("C:\\Windows\\SysWOW64\\cmd.exe"); 36 nativstart.executable=new File("app:/com/cn/config/cmd64/cmd.exe"); 37 //nativstart.executable=new File("C:\\Windows\\System32\\cmd.exe"); 38 39 nativstart.arguments=args; 40 41 nativeProcess=new NativeProcess(); 42 43 nativeProcess.start(nativstart); 44 45 nativeProcess.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onStandardOutPut); 46 nativeProcess.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onStandardError); 47 nativeProcess.addEventListener(IOErrorEvent.STANDARD_ERROR_IO_ERROR, onStandardErrorIo); 48 nativeProcess.addEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, onStandardErrorIo); 49 } 50 51 private function onStandardOutPut(e:ProgressEvent):void { 52 var by:IDataInput=IDataInput(e.target.standardOutput); 53 var outStr:String=by.readMultiByte(by.bytesAvailable, "ansl"); 54 55 if (outStr.indexOf("111") > -1) { 56 outStr=outStr.match(/.*111 +(\w+)?\r\n/g)[0]; 57 var serialNum:String=outStr.replace("111", "").replace(/ +/g, ""); 58 59 param.push(serialNum); 60 61 var vbsfile:File=tmpfile.resolvePath("e.vbs"); 62 if (vbsfile.exists) { 63 //vbsfile.deleteFileAsync(); 64 } 65 66 trace("param:", param) 67 68 NativeApplication.nativeApplication.activeWindow.title=param.toString() + "---" 69 } 70 } 71 72 private function buildToVbs():void { 73 var str:String='MsgValue = ""\n'; 74 str+='Set objWMIService = GetObject("winmgmts:\\\\.\\root\\cimv2")\n'; 75 //''获取硬盘序列号 76 str+='Set colItems = objWMIService.ExecQuery("SELECT * FROM Win32_PhysicalMedia")\n'; 77 str+='For Each objItem In colItems\n'; 78 str+=" Wscript.Echo \"111\" & objItem.SerialNumber \n"; 79 //str+=" exit for ' do the first cpu only! \n"; 80 //str+=' MsgValue = MsgValue & vbCrLf & "硬盘 = " & objItem.SerialNumber\n'; 81 //str+=' MsgValue = objItem.SerialNumber\n'; 82 str+='Next\n'; 83 //str+=''; 84 //str+='Wscript.Echo MsgValue\n'; 85 //str+='set wshshell=createobject("wscript.shell")\n' 86 //str+='wshshell.run "cmd.exe /c echo " & MsgValue &">' + tmpfile.nativePath + '\\i.txt",1,true' 87 88 var f:File=tmpfile.resolvePath("e.vbs"); 89 90 var fs:FileStream=new FileStream(); 91 fs.openAsync(f, FileMode.WRITE); 92 fs.writeMultiByte(str, "ansl"); 93 fs.close(); 94 } 95 96 private function buildToBat():void { 97 var tmpfile:File=File.userDirectory; 98 var f:File=tmpfile.resolvePath("b.vbs"); 99 100 var str:String='set wshshell=createobject(“wscript.shell”)'; 101 str+='wshshell.run “cmd.exe /c cscript ' + tmpfile.nativePath + '\\e.vbs”,0,true'; 102 103 var fs:FileStream=new FileStream(); 104 fs.openAsync(f, FileMode.WRITE); 105 fs.writeMultiByte(str, "ansl"); 106 fs.close(); 107 } 108 109 private function onStandardError(e:ProgressEvent):void { 110 var by:IDataInput=IDataInput(e.target.standardOutput); 111 var b:String=by.readMultiByte(by.bytesAvailable, "ansl") 112 trace(b, "---"); 113 114 NativeApplication.nativeApplication.activeWindow.title=b.toString() + "--33-" 115 } 116 117 private function onStandardErrorIo(e:IOErrorEvent):void { 118 trace(e.target, ">>>") 119 NativeApplication.nativeApplication.activeWindow.title=e.toString() + "-22--" 120 } 121 122 } 123 }
这个在开放是要改下配置文件:
1 <?xml version="1.0" encoding="utf-8" standalone="no"?> 2 <application xmlns="http://ns.adobe.com/air/application/3.1"> 3 <supportedProfiles>extendedDesktop desktop</supportedProfiles>
第3行在配置文件里能找到,大概在118行左右,但是必须放在第3行,否则报错,具体参数看118行说明
下面是118行
1 <!-- We recommend omitting the supportedProfiles element, --> 2 <!-- which in turn permits your application to be deployed to all --> 3 <!-- devices supported by AIR. If you wish to restrict deployment --> 4 <!-- (i.e., to only mobile devices) then add this element and list --> 5 <!-- only the profiles which your application does support. --> 6 <!-- <supportedProfiles>desktop extendedDesktop mobileDevice extendedMobileDevice</supportedProfiles> -->
注意:
如果不把extendedDesktop参数放在前面,在使用NativeProcess时会报错
错误是: (这个意思是当前profile不支持nativeprocess)
1 Error: Error #3219: The NativeProcess could not be started. 'Not supported in current profile.' 2 at Error$/throwError() 3 at flash.desktop::NativeProcess/start()
当然我们可以先用:
1 if (NativeProcess.isSupported)
判断下,这样就不会报错,但是这样还是不能执行,必须配置
而且在配置中,这个的配置必须放在xml文件的第一个节点,
此外,参数: extendedDesktop是第一个时才能使用,但是不能发布,因为没配置desktop这个参数, 默认desktop是在前面的,调换下就好了
自动更新实现:
1 package com.cn.desk { 2 import air.update.ApplicationUpdater; 3 import air.update.ApplicationUpdaterUI; 4 import air.update.events.DownloadErrorEvent; 5 import air.update.events.StatusFileUpdateErrorEvent; 6 import air.update.events.StatusFileUpdateEvent; 7 import air.update.events.StatusUpdateEvent; 8 import air.update.events.UpdateEvent; 9 10 import flash.events.ErrorEvent; 11 import flash.events.ProgressEvent; 12 import flash.filesystem.File; 13 import flash.filesystem.FileMode; 14 import flash.filesystem.FileStream; 15 16 public class AutoUpdate { 17 18 private var updateUI:ApplicationUpdaterUI; 19 20 public function AutoUpdate() { 21 this.init(); 22 } 23 24 private function init():void { 25 26 updateUI=new ApplicationUpdaterUI(); 27 updateUI.configurationFile=new File("app:/com/cn/config/updateConfig.xml") 28 29 updateUI.addEventListener(DownloadErrorEvent.DOWNLOAD_ERROR, onDowloadError); 30 updateUI.addEventListener(ErrorEvent.ERROR, onError); 31 32 updateUI.addEventListener(StatusFileUpdateErrorEvent.FILE_UPDATE_ERROR, onFileUpdateError); 33 updateUI.addEventListener(StatusFileUpdateEvent.FILE_UPDATE_STATUS, onFileUpdateStatus); 34 35 updateUI.addEventListener(ProgressEvent.PROGRESS,onProgress); 36 updateUI.addEventListener(UpdateEvent.INITIALIZED, onUpdateEvent); 37 updateUI.addEventListener(UpdateEvent.BEFORE_INSTALL, onUpdateEvent); 38 updateUI.addEventListener(UpdateEvent.CHECK_FOR_UPDATE, onUpdateEvent); 39 updateUI.addEventListener(UpdateEvent.DOWNLOAD_COMPLETE, onUpdateEvent); 40 updateUI.addEventListener(UpdateEvent.DOWNLOAD_START, onUpdateEvent); 41 updateUI.addEventListener(StatusUpdateEvent.UPDATE_STATUS, onUpdateStatus); 42 43 //if (updateUI.isFirstRun) { 44 // updateUI.updateURL="http://pro.cn/downloadAir/update.xml"; 45 // updateUI.delay=1; 46 updateUI.initialize(); 47 //} 48 } 49 50 private function onProgress(e:ProgressEvent):void{ 51 //trace(e.bytesLoaded,e.bytesTotal) 52 } 53 54 private function onFileUpdateError(e:UpdateEvent):void { 55 trace(e.type, "==="); 56 } 57 58 private function onFileUpdateStatus(e:UpdateEvent):void { 59 trace(e.type, "==="); 60 } 61 62 private function onUpdateEvent(e:UpdateEvent):void { 63 trace(e.type, "===", e); 64 switch (e.type) { 65 case UpdateEvent.INITIALIZED: 66 updateUI.checkNow(); 67 break; 68 case UpdateEvent.CHECK_FOR_UPDATE: 69 trace(updateUI.isFirstRun, updateUI.currentVersion, updateUI.previousVersion); 70 71 break; 72 case UpdateEvent.DOWNLOAD_START: 73 trace(updateUI.isFirstRun, updateUI.currentVersion, updateUI.previousVersion); 74 break; 75 case UpdateEvent.DOWNLOAD_COMPLETE: 76 trace(updateUI.isFirstRun, updateUI.currentVersion, updateUI.previousVersion); 77 break; 78 } 79 } 80 81 private function onDowloadError(e:DownloadErrorEvent):void { 82 trace(e.type, "===", e, "[[",e.target); 83 } 84 85 private function onError(e:DownloadErrorEvent):void { 86 trace(e.type, "==="); 87 } 88 89 private function onUpdateStatus(e:StatusUpdateEvent):void { 90 trace(e.version, e.versionLabel, e.type) 91 92 } 93 94 } 95 }
updateConfig.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration xmlns="http://ns.adobe.com/air/framework/update/configuration/1.0"> <url>http://pro.cn/downloadAir/update.xml</url> <delay>1</delay> </configuration>
服务器端配置update.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <update xmlns="http://ns.adobe.com/air/framework/update/description/2.5"> <versionNumber>0.0.2</versionNumber> <url>http://pro.cn/downloadAir/gameAir_0.0.2.air</url> <description> <![CDATA[ This version has fixes for the following knowns issues: First issue Second issue ]]> </description> </update>
服务器端路径:

以上主要是配置的使用,下面讲发布,使用,和调用第三方文件的过程:
发布(发行版导出):

1): air版导出,不支持NativeProcess,但是可以操作网络,和其他基本as3功能;
2): exe文件导出,这个比较复杂;
源代码:
..........................后边在续
浙公网安备 33010602011771号