2011-06-08 96 views
3

我正在Flash Builder(Flex)中開發AIR應用程序,並且需要與計算機上的串行端口進行通信的選項。所以我使用Serproxy來幫助我。使用Adobe AIR啓動EXE(Serproxy)

我希望能夠在我的應用程序運行時啓動serproxy.exe。我試過兩種方法,但他們都不適合我。

我已使用extendedDesktop設置supportedProfiles。


第一種方法:

var file:File = File.applicationDirectory.resolvePath("assets/serproxy.exe"); 
file.openWithDefaultApplication(); 

這前進到打開程序,但然後立即將其關閉。沒有錯誤被拋出。


方法二:

var file:File = File.applicationDirectory.resolvePath("assets/serproxy.exe"); 

var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo(); 
nativeProcessStartupInfo.executable = file; 
var process:NativeProcess = new NativeProcess(); 

process.start(nativeProcessStartupInfo); 

雖然通過研究這種方法已經發現工作,它根本沒有我的。沒有錯誤發生,並且沒有程序啓動。


如果有人有任何想法,請讓我知道!由於

回答

4

我已經解決了它啓動應用程序。我的問題是,因爲Serproxy以cmd.exe打開,所以有一些問題保持打開文件,因爲Windows喜歡自動關閉它。我周圍這讓通過創建一個快捷方式文件,並與

C:\Windows\System32\cmd.exe /K "C:\...assets\serproxy.exe" 

前未決的目標,然後我可以

var file:File = File.applicationDirectory.resolvePath("assets/serproxy.lnk"); 
file.openWithDefaultApplication(); 

運行該快捷方式,窗口打開呆!

+0

我一直在努力爭取這麼多年!這種方法的一個問題是,如果你打包應用程序,並將其安裝到不同的目錄,快捷方式將會中斷。你有什麼想法如何克服這一點? – davivid 2011-07-14 07:38:28

+0

@davivid好吧,我從來沒有真正得到那麼遠,因爲我最終從Serproxy切換到Python + PySerial - 它是可靠的,在後臺運行並且是跨OS。 您可以使用AIR2中的File類生成.lnk文件。如果.lnk文件不存在,請使用resolvePath獲取serproxy.exe的絕對路徑並生成.lnk文件 - 每次啓動應用程序時。只需在十六進制編輯器中查看.lnk文件的來源即可瞭解如何寫入字節。 – 2011-07-15 02:44:44

-1

使用的URLRequest使用AIR

public function clickButton():void{ 
var request : URLRequest = new URLRequest('C:\\path to serproxy\serproxy.exe'); 
navigateToURL(request) 

also here are the paths to default folders 
var appDir:File = File.applicationDirectory; 
var appStoreDir:File= File.applicationStorageDirectory; 
var desktopDir:File = File.desktopDirectory; 
var docDir:File = File.documentsDirectory; 
var userDir:File = File.userDirectory; 
var rootDirArr:Array = File.getRootDirectories(); 
+1

沒有工作,只是通過我的瀏覽器 「下載」 的文件。還是要謝謝你的幫助。 – 2011-06-09 00:25:43

+1

-1。爲什麼你會使用URLRequest作爲本機應用程序? – 2011-06-09 12:15:15

1

我去年寫的應用程序調用迪斯科桌面它使用TinkerProxy讓空氣通過USB串行端口與Arduino的溝通。我的TinkerProxy/TinkerProxyEvent類在下面發佈。

該應用程序捆綁了serproxy,並使用Native Process API調用它,因此有兩種不同的安裝程序 - Mac OS X和Windows。 TinkerProxy.as擴展了Socket,根據用戶的輸入在運行時寫入serproxy配置文件,並基於此配置啓動serproxy作爲後臺進程。終端/ cmd窗口永遠不可見。注意:調用open()而不是connect()。包含在安裝程序中的是Arduino的簡單設備原理圖和草圖。

這可能不是我最好的代碼,但它確實有效。我希望它有幫助。

廷克代理:

package com.mattie.net 
{ 
//Imports 
import com.mattie.events.TinkerProxyEvent; 
import flash.desktop.NativeApplication; 
import flash.desktop.NativeProcessStartupInfo; 
import flash.desktop.NativeProcess; 
import flash.errors.IOError; 
import flash.events.Event; 
import flash.events.IOErrorEvent; 
import flash.events.SecurityErrorEvent; 
import flash.events.TimerEvent; 
import flash.filesystem.FileMode; 
import flash.filesystem.FileStream; 
import flash.filesystem.File; 
import flash.net.Socket; 
import flash.system.Capabilities; 
import flash.utils.Timer; 
import flash.utils.Endian; 

//Class 
public class TinkerProxy extends Socket 
    { 
    //Properties 
    private var systemIsWindowsProperty:Boolean; 
    private var openingProperty:Boolean; 
    private var connectedProperty:Boolean; 

    //Variables 
    private var windowsProxyFile:String; 
    private var macProxyFile:String; 
    private var tinkerProxyApplication:File; 
    private var tinkerProxyConfigurationFile:File; 
    private var serialPort:String; 
    private var baudRate:uint; 
    private var networkAddress:String; 
    private var networkPort:uint; 
    private var loadDelay:uint; 
    private var loadDelayTimer:Timer; 
    private var initializeDelay:uint; 
    private var initializeDelayTimer:Timer; 
    private var comDatabits:uint; 
    private var comStopbits:uint; 
    private var proxyTimeout:uint; 
    private var writeConfigStream:FileStream; 
    private var tinkerProxyProcess:NativeProcess; 

    //Constructor 
    public function TinkerProxy(windowsProxyFile:String = "serproxy.exe", macProxyFile:String = "serproxy.osx", endian:String = Endian.LITTLE_ENDIAN) 
     { 
     //Set Included File Proxy Names 
     this.windowsProxyFile = windowsProxyFile; 
     this.macProxyFile = macProxyFile; 

     super(); 
     super.endian = endian; 

     init(); 
     } 

    //Resolve The Operating System 
    private function init():void 
     { 
     //Check If Source Tinker Proxy Files Are Included In Application Directory 
     if (!File.applicationDirectory.resolvePath(windowsProxyFile).exists && !File.applicationDirectory.resolvePath(macProxyFile).exists) 
      throw new Error("Tinker Proxy source files \"" + windowsProxyFile + "\" (Windows) and/or \"" + macProxyFile + "\" (Mac) cannot be found in application directory (Included Files)"); 

     //Resoslve Operating System 
     if (Capabilities.os.toLowerCase().indexOf("windows") > -1) 
      { 
      systemIsWindowsProperty = true; 
      tinkerProxyApplication = File.applicationDirectory.resolvePath(windowsProxyFile); 
      tinkerProxyConfigurationFile = File.applicationStorageDirectory.resolvePath(windowsProxyFile.substring(0, windowsProxyFile.lastIndexOf(".exe")) + ".cfg"); 
      } 
      else if (Capabilities.os.toLowerCase().indexOf("mac") > -1) 
      { 
      systemIsWindowsProperty = false; 
      tinkerProxyApplication = File.applicationDirectory.resolvePath(macProxyFile); 
      tinkerProxyConfigurationFile = File.applicationStorageDirectory.resolvePath(macProxyFile + ".cfg"); 
      } 
      else 
      { 
      throw new Error("TinkerProxy Error: Operating System Is Not Supported"); 
      } 
     } 

    //Open Tinker Proxy Socket Connection 
    public function open(
         serialPort:String, 
         baudRate:uint, 
         networkAddress:String = "127.0.0.1", 
         networkPort:uint = 5331, 
         loadDelay:uint = 1000, 
         initializeDelay:uint = 2000, 
         comDatabits:uint = 8, 
         comStopbits:uint = 1, 
         proxyTimeout:uint = 63115200 
         ) 
     { 
     //Disable Opening Socket If Currently Opening 
     if (!openingProperty) 
      { 
      //Set Accessor 
      openingProperty = true; 

      //Dispatch Event 
      dispatchEvent(new TinkerProxyEvent(TinkerProxyEvent.LOADING)); 

      //Check If Connection Parameters For Configuration File Have Changed 
      if (
       this.serialPort == serialPort && 
       this.baudRate == baudRate       && 
       this.networkAddress == networkAddress    && 
       this.networkPort == networkPort      && 
       this.comDatabits == comDatabits      && 
       this.comStopbits == comStopbits      && 
       this.proxyTimeout == proxyTimeout 
       ) 
        { 
        //Assign Timer Variables 
        this.loadDelay = loadDelay; 
        this.initializeDelay = initializeDelay; 

        //Launch Tinker Proxy Application If Connection Parameters Have Not Changed 
        launchTinkerProxyApplication(null); 
        return; 
        } 

      //Assign Variables 
      this.serialPort = serialPort; 
      this.baudRate = baudRate; 
      this.networkAddress = networkAddress; 
      this.networkPort = networkPort; 
      this.loadDelay = loadDelay; 
      this.initializeDelay = initializeDelay; 
      this.comDatabits = comDatabits; 
      this.comStopbits = comStopbits; 
      this.proxyTimeout = proxyTimeout; 

      //Add Event Listeners To New File Stream 
      writeConfigStream = new FileStream(); 
      writeConfigStream.addEventListener(Event.CLOSE, launchTinkerProxyApplication); 
      writeConfigStream.addEventListener(IOErrorEvent.IO_ERROR, IOErrorEventHandler); 

      //Write Tinker Proxy Configuration File 
      writeConfigStream.openAsync(tinkerProxyConfigurationFile, FileMode.WRITE); 

      writeConfigStream.writeUTFBytes("serial_device1=" + serialPort + File.lineEnding); 
      writeConfigStream.writeUTFBytes("comm_ports=1" + File.lineEnding); 
      writeConfigStream.writeUTFBytes("net_port1=" + networkPort + File.lineEnding);    
      writeConfigStream.writeUTFBytes("newlines_to_nils=false" + File.lineEnding); 
      writeConfigStream.writeUTFBytes("comm_baud=" + baudRate + File.lineEnding); 
      writeConfigStream.writeUTFBytes("comm_databits=" + comDatabits + File.lineEnding); 
      writeConfigStream.writeUTFBytes("comm_stopbits=" + comStopbits+ File.lineEnding); 
      writeConfigStream.writeUTFBytes("comm_parity=none" + File.lineEnding); 
      writeConfigStream.writeUTFBytes("timeout=" + proxyTimeout + File.lineEnding); 

      writeConfigStream.close(); 
      } 
     } 

    //Launch Tinker Proxy Application 
    private function launchTinkerProxyApplication(evt:Event):void 
     { 
     if (evt) 
      { 
      //Remove File Stream Event Listeners 
      writeConfigStream.removeEventListener(Event.CLOSE, launchTinkerProxyApplication); 
      writeConfigStream.removeEventListener(IOErrorEvent.IO_ERROR, IOErrorEventHandler); 
      } 

     //Start Tinker Proxy Application As Native Process 
     var tinkerProxyProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo(); 
     tinkerProxyProcessStartupInfo.executable = tinkerProxyApplication; 

     var processArguments:Vector.<String> = new Vector.<String>(); 
     processArguments[0] = tinkerProxyConfigurationFile.nativePath; 
     tinkerProxyProcessStartupInfo.arguments = processArguments; 

     tinkerProxyProcess = new NativeProcess(); 
     tinkerProxyProcess.start(tinkerProxyProcessStartupInfo); 

     //Delay Process To Allow Tinker Proxy Application To Initialize 
     loadDelayTimer = new Timer(loadDelay, 1); 
     loadDelayTimer.addEventListener(TimerEvent.TIMER_COMPLETE, connectTinkerProxy); 
     loadDelayTimer.start(); 
     } 

    //Initialize Tinker Proxy Socket Connection 
    private function connectTinkerProxy(evt:TimerEvent):void 
     { 
     //Dispatch Event 
     dispatchEvent(new TinkerProxyEvent(TinkerProxyEvent.INITIALIZING)); 

     //Remove Tinker Proxy Application Initilization Timer 
     loadDelayTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, connectTinkerProxy); 
     loadDelayTimer = null; 

     //Add Connection Error Event Listeners 
     addEventListener(Event.CONNECT, initializeDelayTimerHandler); 
     addEventListener(Event.CLOSE, connectionErrorEventHandler); 
     addEventListener(IOErrorEvent.IO_ERROR, connectionErrorEventHandler); 
     addEventListener(SecurityErrorEvent.SECURITY_ERROR, connectionErrorEventHandler); 

     //Connect Socket (Super) 
     try { 
      super.connect(networkAddress, networkPort); 
      } 
      catch(error:IOError)  {connectionErrorEventHandler(null);} 
      catch(error:SecurityError) {connectionErrorEventHandler(null);} 
     } 

    //Delay Process To Allow Device To Initialize 
    private function initializeDelayTimerHandler(evt:Event):void 
     { 
     removeEventListener(Event.CONNECT, initializeDelayTimerHandler); 

     initializeDelayTimer = new Timer(initializeDelay, 1); 
     initializeDelayTimer.addEventListener(TimerEvent.TIMER_COMPLETE, tinkerProxyConnectionComplete); 
     initializeDelayTimer.start(); 
     } 

    //Tinker Proxy Socket Has Been Successfully Connected 
    private function tinkerProxyConnectionComplete(evt:TimerEvent):void 
     { 
     //Set Accessors 
     openingProperty = false; 
     connectedProperty = true; 

     //Dispatch Event 
     dispatchEvent(new TinkerProxyEvent(TinkerProxyEvent.CONNECT)); 

     //Remove Device Initilization Timer 
     initializeDelayTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, tinkerProxyConnectionComplete); 
     initializeDelayTimer = null; 
     } 

    //Throw Error If Stock Connect Method Is Explicitly Called 
    override public function connect(host:String, port:int):void 
     { 
     throw new Error("Cannot call connect() method on TinkerProxy instance. Call open() method instead."); 
     } 

    //Close Tinker Proxy Application 
    override public function close():void 
     { 
     //Stop Configuration File And Timers If Socket Is Currently Opening 
     if (openingProperty) 
      { 
      //Set Accessor 
      openingProperty = false; 

      //Stop File Stream 
      if (writeConfigStream.hasEventListener(Event.CLOSE)) 
       { 
       writeConfigStream.close(); 
       writeConfigStream.removeEventListener(Event.CLOSE, launchTinkerProxyApplication); 
       writeConfigStream.removeEventListener(IOErrorEvent.IO_ERROR, IOErrorEventHandler); 
       } 

      //Stop Process Initialization Timer 
      if (loadDelayTimer.running) 
       { 
       loadDelayTimer.stop(); 
       loadDelayTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, connectTinkerProxy); 
       loadDelayTimer = null; 
       } 

      //Stop Device Initialization Timer 
      if (initializeDelayTimer.running) 
       { 
       initializeDelayTimer.stop(); 
       initializeDelayTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, connectTinkerProxy); 
       initializeDelayTimer = null; 
       } 
      } 

     //Close Socket (Super) 
     super.close(); 

     //Close Tinker Proxy Application 
     tinkerProxyProcess.exit(true); 
     tinkerProxyProcess = null; 

     //Dispatch Event 
     dispatchEvent(new TinkerProxyEvent(TinkerProxyEvent.DISCONNECT)); 

     //Set Accessor 
     connectedProperty = false; 

     //Remove Connection Error Event Listeners 
     removeEventListener(Event.CLOSE, connectionErrorEventHandler); 
     removeEventListener(IOErrorEvent.IO_ERROR, connectionErrorEventHandler); 
     removeEventListener(SecurityErrorEvent.SECURITY_ERROR, connectionErrorEventHandler); 
     } 

    //Server Automatically Closed The Socket Due To A Connection Error 
    private function connectionErrorEventHandler(evt:*):void 
     { 
     //Set Accessors 
     openingProperty = false; 
     connectedProperty = false; 

     //Dispatch Event 
     dispatchEvent(new TinkerProxyEvent(TinkerProxyEvent.ERROR)); 

     //Remove Device Initilization Timer 
     if (initializeDelayTimer != null) 
      { 
      if (initializeDelayTimer.running) 
       initializeDelayTimer.stop(); 

      initializeDelayTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, tinkerProxyConnectionComplete); 
      initializeDelayTimer = null; 
      } 

     //Remove Connection Error Event Listeners 
     removeEventListener(Event.CLOSE, connectionErrorEventHandler); 
     removeEventListener(IOErrorEvent.IO_ERROR, connectionErrorEventHandler); 
     removeEventListener(SecurityErrorEvent.SECURITY_ERROR, connectionErrorEventHandler); 

     //Close Tinker Proxy Application 
     tinkerProxyProcess.exit(true); 
     tinkerProxyProcess = null; 
     } 

    //IO Error Event Handler 
    private function IOErrorEventHandler(evt:IOErrorEvent):void 
     { 
     throw new Error("TinkerProxy IOError: " + evt); 
     } 

    //Accessors 
    public function get systemIsWindows():Boolean 
     { 
     return systemIsWindowsProperty; 
     } 

    public function get opening():Boolean 
     { 
     return openingProperty; 
     } 

    override public function get connected():Boolean 
     { 
     return connectedProperty; 
     } 
    } 
} 

廷克代理事件:

package com.mattie.events 
{ 
//Imports 
import flash.events.Event; 

//Class 
public class TinkerProxyEvent extends Event 
    { 
    //Constants 
    public static const LOADING:String = "Loading"; 
    public static const INITIALIZING:String = "Initializing"; 
    public static const CONNECT:String = "Connect"; 
    public static const DISCONNECT:String = "Disconnect"; 
    public static const ERROR:String = "Error"; 

    //Constructor 
    public function TinkerProxyEvent(type:String, bubbles:Boolean = false, cancelable:Boolean = false) 
     { 
     super(type, bubbles, cancelable); 
     } 
    } 
} 

安裝程序:Disco Desktop (Mac Installer)Disco Desktop (Windows Installer)