AIR 本机流程标准输入未连接到应用程序

本文关键字:连接 应用程序 标准输入 本机 AIR | 更新日期: 2023-09-27 17:56:17

我正在编写一个启动 C# 控制台应用程序的 AIR 应用程序,它们需要通信。 我想为此使用标准输入/标准输出,但是我似乎无法让它工作。

当 C# 应用从标准输入获取输入时,它应该通过标准输出将其发送回,如果它收到"exit",则退出。 我可以从命令行对此进行测试,并且可以正常工作。 当我从 AIR 发送字符串时,我没有得到来自 C# 应用的响应。

我在启动 C# 应用程序时发送了一个参数,并且确实从中得到了响应,因此我的 AIR 应用程序至少能够从标准输出接收消息,它只是标准输入不起作用。 当我通过 standardInput 从 AIR 发送消息时,当我发送密钥代码时,我会收到一个进度事件,其中 bytesLoaded = 3,当我发送"exit"命令时,bytesLoaded = 5。

下面是 C# 代码:

static void Main(string[] args)
{
    if (args.Length > 0)
    {
        Console.WriteLine(args[0]);
    }
    while (true)
    {
        string incoming = Console.ReadLine();
        string outgoing = "received: " + incoming;
        Console.WriteLine(outgoing);
        if (incoming == "exit")
            return;
    }
}

这是AS3代码:

private function init(e:Event=null):void {
    this.removeEventListener(Event.ADDED_TO_STAGE, init);
    NativeApplication.nativeApplication.addEventListener(Event.EXITING, onAppClose);
    var info:NativeProcessStartupInfo = new NativeProcessStartupInfo();
    var file:File = File.applicationDirectory.resolvePath("test.exe");
    info.executable = file;
    process = new NativeProcess();
    info.arguments.push("native process started");
    process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);
    process.addEventListener(ProgressEvent.STANDARD_ERROR_DATA, onErrorData);
    process.addEventListener(ProgressEvent.STANDARD_INPUT_PROGRESS, onInputProgress);
    process.addEventListener(Event.STANDARD_OUTPUT_CLOSE, onOutputClose);
    process.addEventListener(Event.STANDARD_ERROR_CLOSE, onErrorClose);
    process.addEventListener(IOErrorEvent.STANDARD_ERROR_IO_ERROR, onIOError);
    process.addEventListener(IOErrorEvent.STANDARD_INPUT_IO_ERROR, onIOError);
    process.addEventListener(IOErrorEvent.STANDARD_OUTPUT_IO_ERROR, onIOError);
    stage.addEventListener(KeyboardEvent.KEY_UP, onKeyUp);
    process.start(info);
}
private function onKeyUp(e:KeyboardEvent):void {
    if (e.keyCode == Keyboard.ESCAPE) 
        process.standardInput.writeUTFBytes("exit'n");
    else {
        var msg:String = e.keyCode + "'n";
        process.standardInput.writeUTFBytes(msg);
    }
}
private function onOutputData(e:ProgressEvent):void {
    var data:String = process.standardOutput.readUTFBytes(process.standardOutput.bytesAvailable); 
    trace("Got: ", data); 
}

AIR 本机流程标准输入未连接到应用程序

几个月前我遇到了这个问题,但我从未解决过它,因为我只是使用命令行参数代替。我刚刚回到它,因为我渴望知道发生了什么。

我现在发现,以 .NET 3.5 或更早版本为目标使其按预期工作。切换回 v4.0,我在标准上一无所获。我不确定问题出在哪里,但如果您可以使用 v3.5,那么它可能是您的解决方案。

如果除了我之外的其他人仍然将Adobe AIR与C#控制台应用程序一起使用,以下是该问题的解决方案:

就像 @tom-makin 在链接答案中指出的那样,你需要创建另一个在 .NET 3.5 上运行的控制台应用,然后打开较新的 .NET 控制台应用并将输入传递给它。这是我对这样一个应用程序的看法:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Threading;
namespace StdInPiper
{
    class Program
    {
        static void Main(string[] args)
        {
            // Remove the first arg from args, containing the newer .NET exePath.
            string exePath = args[0];
            var tempArgs = new List<string>(args);
            tempArgs.RemoveAt(0);
            string argsLine = "";
            foreach (string arg in tempArgs)
            {
                argsLine = argsLine + " " + arg;
            }
            argsLine = argsLine.Trim();
            var process = new Process();            
            process.EnableRaisingEvents = true;
            process.StartInfo.UseShellExecute = false;            
            process.StartInfo.RedirectStandardOutput = true;
            process.StartInfo.RedirectStandardError = true;
            process.StartInfo.RedirectStandardInput = true;
            process.StartInfo.Arguments = argsLine;
            process.StartInfo.FileName = exePath;
            process.OutputDataReceived += (sender, eventArgs) =>
            {
                Console.Write(eventArgs.Data);
            };
            process.ErrorDataReceived += (sender, eventArgs) =>
            {
                Console.Error.Write(eventArgs.Data);
            };
            process.Exited += (sender, eventArgs) =>
            {
                process.CancelOutputRead();
                process.CancelErrorRead();
                Environment.Exit(Environment.ExitCode);
            };
            process.Start();            
            process.BeginOutputReadLine();
            process.BeginErrorReadLine();                        
            while (true)
            {
                Thread.Sleep(20);
                string line = Console.ReadLine();
                if (line != null)
                {
                    process.StandardInput.WriteLine(line);
                }
            }            
        }
    }
}