输入cmd进程的用户名

时间:2011-03-09 07:10:54

标签: c# process input cmd

在我的Winform应用程序中,我使用cmd Process执行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要求输入用户名然后是passowrd,那么他们就没有输入了。我得到适当的控制台输出,但结果不如预期。这是代码:

        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之后退出 Line = Fri Mar 11 18:10:06 2011 OpenVPN 2.1.1 i686-pc-mingw32 [SSL] [LZO2] [PKCS11]建于2010年2月17日 写详细信息//在第1行之后是TRYNG写的 写了用户名 写了密码 Line = Fri Mar 11 18:10:06 2011 ERROR:无法从stdin读取Auth用户名 Line = Fri Mar 11 18:10:06 2011退出 线= 完成cmd

无法确定应用程序是否无法正确地将输入输入到stdin,或者openvpn无法接受它。我也尝试了sw.WriteLine(“foo”+ ConsoleKey.Enter);,也产生了相同的结果。想知道&尝试在执行/调试时看到cmd窗口以了解确切的结果,但也看不到它。

如果我们正常通过命令提示符运行openvpn,我们得到的是:

D:\>files\\openvpn --config files\\client.ovpn

Fri Mar 11 18:03:48 2011 OpenVPN 2.1.1 i686-pc-mingw32 [SSL] [LZO2] [PKCS11] bui 在2010年2月17日 输入验证用户名:

真的很困惑。

3 个答案:

答案 0 :(得分:1)

您实际上是在finally块中关闭了您的流程。尝试在process.WaitForExit();

之前添加Console.WriteLine("Finished cmd");

或者,您可以将process.BeginOutputReadLine();替换为:

while (!process.HasExited)
{
    string d = process.StandardOutput.ReadLine();
    Console.WriteLine("Line = {0}", d);
}

更好的方法是将make process作为成员变量而不是局部变量。简单地将finally块中的代码移动到流程退出处理程序:

void process_Exited(object sender, EventArgs e)
{
    // Code from finally here
}

但是你必须记得添加退出的处理程序:

process.Exited += new EventHandler(process_Exited);

另一方面,关闭输入流可能会导致一些问题。尝试删除以下2行以查看会发生什么

sw.Flush();
sw.Close();

以下是您的代码的编辑版本:

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); // Actually no longer required, since HasExited will test for it
    // return; // return not required
}

// No longer need Exited, since HasExited checks for it
/*
void process_Exited(object sender, EventArgs e)
{
    Console.WriteLine("Into process_Exited....");
    processInfo = null;
    if (process != null)
    {
        sw = null;
        // Do not close here. Closing here will prevent "process.WaitForExit()" and "process.HasExited" from working
        //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(); // Not required, since HasExited already check whether process has exited
        // Added here from Exited, so that it only close after exit
        process.Close();
        process = null;
        Console.WriteLine("Finished cmd");
    }
    catch (Exception e)
    {
        Console.WriteLine("Errror Opening : " + e.Message);
        Console.WriteLine(e.StackTrace);
    }

    return installed;
}

答案 1 :(得分:0)

不要试图通过命令行传递用户名和密码,而是使用OpenVPN的--auth-user-pass [file]开关,其中[file]是两行:

  

用户   secretPassword的

我从未尝试过,但它是文档所说的。

所以你打开的行就像是:

string command = "files\\openvpn --config files\\client.ovpn --auth-user-pass files\\TEMP-AUTH";

请记得在完成后立即删除TEMP-AUTH。

答案 2 :(得分:0)

此查询对我来说无法解析,因为openvpn不支持从应用程序接受stdin。

感谢大家的帮助,意见和建议。

感谢。

相关问题