【发布时间】:2011-03-09 07:10:54
【问题描述】:
在我的 Winform 应用程序中,我使用 cmd 进程执行一个 exe 文件。 exe文件需要在“输入用户名”和“输入密码”行输入用户名和密码。我无法输入用户名和密码,不知何故该过程仅退出并且仅不起作用。我还添加了对 ThreadState 和 WaitReason 的检查,但 process.Threads 中没有线程。我也需要输出。如果我在输入过程之前输入输出,那么它直到输入才会到达,如果我在输出之前输入输入,那么输入也不会被接受。只需始终接收相同的输出。这是代码:
public bool StartOpenVPN()
{
bool installed = false;
ProcessStartInfo processInfo = null;
Process process = null;
try
{
string command = "files\\openvpn --config files\\client.ovpn";
Console.WriteLine("Command = " + command);
processInfo = new ProcessStartInfo("cmd.exe", "/C " + command);
processInfo.UseShellExecute = false;
processInfo.RedirectStandardInput = true;
processInfo.RedirectStandardOutput = true;
Console.WriteLine("Opening cmd");
process = new Process();
process.StartInfo = processInfo;
process.Start();
StreamWriter sw = process.StandardInput;
sw.WriteLine("foo");
sw.WriteLine("*baa");
sw.Flush();
sw.Close();
process.BeginOutputReadLine();
process.OutputDataReceived += new DataReceivedEventHandler(Process_OutputDataReceived);
Console.WriteLine("Finished cmd");
}
catch (Exception e)
{
Console.WriteLine("Errror Installing Tap Adapter : " + e.Message);
Console.WriteLine(e.StackTrace);
}
finally
{
processInfo = null;
if (process != null)
{
process.Close();
process = null;
}
}
return installed;
}
private void Process_OutputDataReceived(object sender, DataReceivedEventArgs e)
{
string d = e.Data;
if (!string.IsNullOrEmpty(d))
{
Console.WriteLine("Line = " + d);
}
}
我得到的唯一输出是:
Line = Wed Mar 09 12:33:00 2011 OpenVPN 2.1.1 i686-pc-mingw32 [SSL] [LZO2] [PKCS11] built on Feb 17 2010
Line = Wed Mar 09 12:33:00 2011 ERROR: could not read Auth username from stdin
Line = Wed Mar 09 12:33:00 2011 Exiting
为什么它不接受输入,甚至在输出中显示“输入用户名”行?我无法确定我哪里出错了,但它似乎在某个地方出错了。请帮我解决这个问题,我被严重卡住了,已经尝试了很多次,并且在此之后花了很多时间。
非常感谢任何帮助。
谢谢
@Fun Mun :这是更新的代码。它只是去 process_Exited 获取任何流输入/输出:
private void initProcess()
{
processInfo = new ProcessStartInfo("cmd.exe", "/C " + command);
processInfo.UseShellExecute = false;
processInfo.RedirectStandardInput = true;
processInfo.RedirectStandardOutput = true;
processInfo.WindowStyle = ProcessWindowStyle.Normal;
process = new Process();
process.StartInfo = processInfo;
process.Exited += new EventHandler(process_Exited);
return;
}
void process_Exited(object sender, EventArgs e)
{
Console.WriteLine("Into process_Exited....");
processInfo = null;
if (process != null)
{
sw = null;
process.Close();
process = null;
}
}
public bool StartOpenVPN()
{
bool installed = false;
try
{
Console.WriteLine("Command = " + command);
Console.WriteLine("Opening cmd");
initProcess();
process.Start();
sw = process.StandardInput;
Console.WriteLine("Has Exited after SW = " + process.HasExited.ToString()); // RETURS FALSE BUT GOES TO process_Exited & for next line results is NullPointerException
sw.WriteLine("foo");
sw.WriteLine("*baa");
//sw.Flush();
//sw.Close();
//process.BeginOutputReadLine();
//process.OutputDataReceived += new DataReceivedEventHandler(Process_OutputDataReceived);
while (process.HasExited == false)
{
string d = process.StandardOutput.ReadLine();
Console.WriteLine("Line = " + d);
}
process.WaitForExit();
Console.WriteLine("Finished cmd");
}
catch (Exception e)
{
Console.WriteLine("Errror Opening : " + e.Message);
Console.WriteLine(e.StackTrace);
}
return installed;
}
直到 process.BeginOutputReadLine(); & 输出处理程序没有被删除,它一直在等待(可能是为了进入),就像挂出一样。删除这两条输出线并添加 while 循环的那一刻,进程只会在任何流调用中退出,即 process.StandardOutput;或 StandardInput 以后者为准并抛出 NullPointerException。 我是否按照您的指示在代码中犯了任何错误?
@Fun Mum :即使在使用和更新您编辑的代码版本之后,我的结果还是一样。我更新了您的代码,对其进行了一些修改,发现在第一行输出之后,openvpn 要求输入用户名,然后输入密码,然后它们就没有输入。我得到了正确的控制台输出,但结果不如预期。这是代码:
public bool StartOpenVPN()
{
bool installed = false;
int lineNo = 0;
try
{
Console.WriteLine("Command = " + command + "\nOpening cmd");
initProcess();
process.Start();
sw = process.StandardInput;
Console.WriteLine("Has Exited after SW = " + process.HasExited.ToString());
//sw.WriteLine("123b5df33f");
//sw.WriteLine("*3FgYxyt");
//Console.WriteLine("Has Exited after writing data = " + process.HasExited.ToString());
while (process.HasExited == false)
{
string d = process.StandardOutput.ReadLine();
Console.WriteLine("Line = " + d);
lineNo++;
if (lineNo == 1)
{
Console.WriteLine("Writing Details");
sw.WriteLine("foo");
sw.Flush();
Console.WriteLine("Wrote Username");
sw.WriteLine("*baa");
sw.Flush();
Console.WriteLine("Wrote Password");
}
}
process.Close();
process = null;
Console.WriteLine("Finished cmd");
}
catch (Exception e)
{
Console.WriteLine("Errror Installing Tap Adapter : " + e.Message);
Console.WriteLine(e.StackTrace);
}
return installed;
}
输出是:
Command = files\openvpn --config files\client.ovpn
打开cmd 在 SW = False 后退出 线路 = Fri Mar 11 18:10:06 2011 OpenVPN 2.1.1 i686-pc-mingw32 [SSL] [LZO2] [PKCS11] 建于 2010 年 2 月 17 日 写作细节//在第一行之后,它正在尝试写作 写用户名 写密码 Line = Fri Mar 11 18:10:06 2011 错误:无法从标准输入读取 Auth 用户名 线路 = 2011 年 3 月 11 日星期五 18:10:06 退出 线 = 完成cmd
无法确定应用程序是否无法正确地将输入输入到标准输入或 openvpn 无法接受它。我还尝试了 sw.WriteLine("foo" + ConsoleKey.Enter);,也产生了相同的结果。在执行/调试时想知道并尝试查看 cmd 窗口以了解确切结果,但也看不到。
如果我们通过命令提示符正常运行openvpn,我们得到的是:
D:\>files\\openvpn --config files\\client.ovpn
2011 年 3 月 11 日星期五 18:03:48 OpenVPN 2.1.1 i686-pc-mingw32 [SSL] [LZO2] [PKCS11] bui 2010 年 2 月 17 日 输入验证用户名:
对此感到困惑,真的。
【问题讨论】: