2011-06-08 54 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)