我正在编写一个AIR应用程序,启动一个C#控制台应用程序,它们需要进行通信。 我想使用标准输入标准输出来实现这个功能,但是我似乎无法让它工作。
当C#应用程序从标准输入中获得输入时,它应该通过标准输出将其发送回来,如果它收到 "exit",那么它就会退出。 我可以从命令行进行测试,它可以正确工作。 当我从AIR发送一个字符串时,我没有从C#应用程序中得到任何响应。
当我启动C#应用程序时,我正在发送一个参数,我确实从中得到了响应,所以我的AIR应用程序至少能够从标准输出中接收消息,只是标准输入不起作用。 当我通过standardInput从AIR发送消息时,当我发送keycode时,我得到一个进度事件,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);
}
几个月前,我遇到了这个问题,但我从来没有解决它,因为我只是用命令行参数代替。我刚刚回到这个问题上,因为我很想知道是怎么回事。
我现在发现,针对.NET 3.5或更早的版本,它可以像我预期的那样工作。切换回v4.0,我在stdin上什么都没有得到。我不太确定问题出在哪里,但如果你能用v3.5解决,那么它可能是你的一个解决方案。
如果除了我之外还有人还在使用Adobe AIR和C#控制台应用程序,这里有一个解决问题的方法。
就像 @tom-makin 在 "Adobe AIR "中指出的那样。连答你需要创建另一个运行在.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);
}
}
}
}
}