Запустите EXE (Serproxy) с помощью Adobe AIR - PullRequest
3 голосов
/ 09 июня 2011

Я разрабатываю приложение AIR во Flash Builder (Flex), и мне потребовалась опция для связи с последовательным портом на компьютере.Поэтому я использую Serproxy , чтобы помочь мне с этим.

Я хочу иметь возможность запускать serproxy.exe при запуске моего приложения.Я пробовал два метода, и ни один из них не работает для меня.

Я установил SupportProfiles с extendedDesktop.


Первый метод:

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 ]

4 голосов
/ 09 июня 2011

Я решил это. Моя проблема заключалась в том, что, поскольку 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 голос
/ 09 июня 2011

В прошлом году я написал приложение под названием Disco Desktop, которое использует TinkerProxy для связи AIR с Arduino через последовательный порт USB.Мои классы TinkerProxy и TinkerProxyEvent размещены ниже.

Приложение связывает serproxy и использует API-интерфейс Native Process для его вызова, поэтому существует 2 различных установщика - Mac OS X и Windows.TinkerProxy.as расширяет Socket, записывает файл конфигурации serproxy во время выполнения согласно вводу пользователя и запускает serproxy на основе этой конфигурации в качестве фонового процесса.Окно терминала / cmd никогда не отображается.

Примечание: вызов open() вместо connect().В установщики включены простая схема устройства и эскиз для Arduino.

TinkerProxy:

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;
        }
    }
}

TinkerProxyEvent:

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);
        }
    }
}
0 голосов
/ 09 июня 2011

Используйте 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();  
...