使用Adobe AIR启动EXE(Serproxy)

时间:2011-06-08 23:54:48

标签: flex actionscript-3 air flash-builder

我正在Flash Builder(Flex)中开发AIR应用程序,我需要选项与计算机上的串行端口进行通信。所以我正在使用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);

虽然通过研究发现这种方法有效,但它对我没有任何作用。不会抛出任何错误,也不会启动任何程序。


如果有任何想法请告诉我!感谢

3 个答案:

答案 0 :(得分: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();

窗户一直开着!

答案 1 :(得分:1)

我去年写了一个名为 Disco Desktop 的应用程序,该应用程序使用TinkerProxy允许AIR通过USB串口与Arduino进行通信。我的TinkerProxy / TinkerProxyEvent类发布在下面。

应用程序捆绑了serproxy并使用Native Process API来调用它,因此有2个不同的安装程序 - Mac OS X和Windows。 TinkerProxy.as扩展了Socket,根据用户的输入在运行时写入serproxy配置文件,并基于此配置启动serproxy作为后台进程。终端/ cmd窗口永远不可见。注意:调用open()而不是connect()。包含在安装程序中的是Arduino的简单设备原理图和草图。

它可能不是我最好的代码,但确实有效。我希望它有所帮助。

Tinker Proxy:

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)

答案 2 :(得分:-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();