Trouble Starting Selenium Process from a Console Application
Let me be clear: - I have Java.exe in my path environment variable - So if I want to run a "selenium-server" I will do :
1. Start cmd.exe
Microsoft Windows [Version 5.2.3790]
(C) Copyright 1985-2003 Microsoft Corp.
C:\Documents and Settings\cnguyen>
2. Then:
C:\Documents and Settings\cnguyen>cd C:\Selenium RC 0.9.2\selenium-server-0.9.2
3. Next, I'm in the directory that I want so I run:
C:\Documents and Settings\cnguyen>cd C:\Selenium RC 0.9.2\selenium-server-0.9.2
C:\Selenium RC 0.9.2\selenium-server-0.9.2>java -jar selenium-server.jar
09:26:18.586 INFO - Java: Sun Microsystems Inc. 16.3-b01
09:26:18.586 INFO - OS: Windows 2003 5.2 x86
09:26:18.586 INFO - v0.9.2 [2006], with Core v0.8.3 [1879]
09:26:18.633 INFO - Version Jetty/5.1.x
09:26:18.633 INFO - Started HttpContext[/selenium-server/driver,/selenium-server
/driver]
09:26:18.633 INFO - Started HttpContext[/selenium-server,/selenium-server]
09:26:18.633 INFO - Started HttpContext[/,/]
09:26:18.648 INFO - Started SocketListener on 0.0.0.0:4444
09:26:18.648 INFO - Started org.mortbay.jetty.Server@16a55fa
And here is what I got so far, it compiled but not showing anything :(
using System;
using System.IO;
using System.Collections.Generic;
using开发者_开发问答 System.Linq;
using System.Text;
using System.Diagnostics;
namespace SeleniumProcessExample
{
public class SeleniumProcess
{
private Process pro;
public SeleniumProcess()
{
pro = new Process();
Directory.SetCurrentDirectory( @"C:\Selenium RC 0.9.2\selenium-server-0.9.2" );
pro.StartInfo.FileName = "java";
pro.StartInfo.Arguments = " -jar selenium-server.jar";
pro.StartInfo.RedirectStandardOutput = true;
pro.StartInfo.RedirectStandardError = true;
pro.StartInfo.UseShellExecute = false;
pro.Start();
string strOutput = pro.StandardOutput.ReadToEnd();
string strError = pro.StandardError.ReadToEnd();
Console.WriteLine( strOutput );
Console.WriteLine( strError );
Console.Out.Flush();
pro.CloseMainWindow();
}
}
}
EDIT: if you intent is to hide the selenium-server output window, you're going to have to make some asynchronous calls. I can go into the details if this is indeed your intent.
I would love to see this. Would you mind showing me how to do this? Thanks a lot for your suggestion ;)
This works for me...
/// <summary>
/// Creates new process to run and executable file, and return the output
/// </summary>
/// <param name="program">The name of the executable to run</param>
/// <param name="arguments">Any parameters that are required by the executable</param>
/// <param name="silent">Determines whether or not we output execution details</param>
/// <param name="workingDirectory">The directory to run the application process from</param>
/// <param name="standardErr">The standard error from the executable. String.Empty if none returned.</param>
/// <param name="standardOut">The standard output from the executable. String.Empty if none returned, or silent = true</param>
/// <returns>The application's exit code.</returns>
public static int Execute(string program, string arguments, bool silent, string workingDirectory, out string standardOut, out string standardErr)
{
standardErr = String.Empty;
standardOut = String.Empty;
//sometimes it is not advisable to output the arguments e.g. passwords etc
if (!silent)
{
Console.WriteLine(program + " " + arguments);
}
Process proc = Process.GetCurrentProcess();
if (!string.IsNullOrEmpty(workingDirectory))
{
//execute from the specific working directory if specified
proc.StartInfo.WorkingDirectory = workingDirectory;
}
proc.EnableRaisingEvents = true;
proc.StartInfo.FileName = program;
proc.StartInfo.Arguments = arguments;
proc.StartInfo.CreateNoWindow = true;
proc.StartInfo.UseShellExecute = false;
proc.StartInfo.RedirectStandardOutput = true;
proc.StartInfo.RedirectStandardError = true;
proc.Start();
proc.WaitForExit();
//only display the console output if not operating silently
if (!silent)
{
if (proc.StandardOutput != null)
{
standardOut = proc.StandardOutput.ReadToEnd();
Console.WriteLine(standardOut);
}
}
if (proc.StandardError != null)
{
standardErr = proc.StandardError.ReadToEnd();
Console.WriteLine(standardErr);
}
proc.StandardOutput.Close();
proc.StandardError.Close();
return proc.ExitCode;
}
Your pro.StandardOutput.ReadToEnd()
call will block until the executable terminates. Since you're starting a server that will launch and wait for output, you'll never get anything.
If you just want to see the output of the server, set UseShellExecute
to true and RedirectStandardOutput
and RedirectStandardError
to false. (or just delete those three lines) This will cause a new console window to open and show the output from selenium-server.
EDIT: if you intent is to hide the selenium-server output window, you're going to have to make some asynchronous calls. I can go into the details if this is indeed your intent.
I would start by changing the code for the process to this to see if it starts java.exe
pro = new Process();
pro.StartInfo.FileName = @"C:\Selenium RC 0.9.2\selenium-server-0.9.2\java.exe";
pro.StartInfo.Arguments = " -jar selenium-server.jar";
pro.StartInfo.RedirectStandardOutput = true;
pro.StartInfo.RedirectStandardError = true;
pro.StartInfo.UseShellExecute = false;
pro.Start();
Chances are that your program is blocking on the call to pro.StandardOutput.ReadToEnd()
. Consider using the non-blocking BeginOutputReadLine()
method (more at http://msdn.microsoft.com/en-us/library/system.diagnostics.process.beginoutputreadline.aspx and http://msdn.microsoft.com/en-us/library/system.diagnostics.process.standardoutput.aspx).
class LaunchJava
{
private static Process myProcessProcess;
private static StreamWriter myProcessStandardInput;
private static Thread thist = Thread.CurrentThread;
public static void DoJava()
{
// Initialize the process and its StartInfo properties.
// The sort command is a console application that
// reads and sorts text input.
myProcess= new Process();
myProcess.StartInfo.Arguments = "-jar selenium-server.jar";
myProcess.StartInfo.FileName = @"C:\Documents and Settings\cnguyen\java.exe";
// Set UseShellExecute to false for redirection.
myProcess.StartInfo.UseShellExecute = false;
// Redirect the standard output of the sort command.
// This stream is read asynchronously using an event handler.
myProcess.StartInfo.RedirectStandardOutput = true;
myProcessOutput = new StringBuilder("");
// Set our event handler to asynchronously read the sort output.
myProcess.OutputDataReceived += new DataReceivedEventHandler(myProcessOutputHandler);
// Redirect standard input as well. This stream
// is used synchronously.
myProcess.StartInfo.RedirectStandardInput = true;
Console.WriteLine("Start.");
// Start the process.
myProcess.Start();
// Use a stream writer to synchronously write the sort input.
myProcessStandardInput = myProcess.StandardInput;
// Start the asynchronous read of the sort output stream.
myProcess.BeginOutputReadLine();
// Wait for the process to end on its own.
// as an alternative issue some kind of quit command in myProcessOutputHandler
myProcess.WaitForExit();
// End the input stream to the sort command.
myProcessInput.Close();
myProcessProcess.Close();
}
private static void myProcessOutputHandler(object sendingProcess, DataReceivedEventArgs Output)
{
// do interactive work here if needed...
if (!String.IsNullOrEmpty(Output.Data))
{ myProcess.StandardInput.BaseStream.Write(bytee,0,bytee.GetLength);
}
}
精彩评论