xtd 0.2.0
Loading...
Searching...
No Matches

◆ standard_output()

std::istream & xtd::diagnostics::process::standard_output ( )

Gets a stream used to read the textual output of the application.

Returns
A std::istream that can be used to read the standard output stream of the application.
Exceptions
xtd::invalid_operation_exceptionThere is no process associated with this xtd::diagnostics::process object.
Examples
The following example runs the ipconfig.exe command and redirects its standard output to the example's console window.
#include <xtd/xtd>
using namespace xtd;
using namespace xtd::diagnostics;
using namespace xtd::io;
auto main() -> int {
process.start_info().file_name("ipconfig");
// Synchronously read the standard output of the spawned process.
string output = reader.read_to_end();
// Write the redirected output to this application's window.
}
console::write_line("\n\nPress any key to exit.");
}
static xtd::string read_line()
Reads the next line of characters from the standard input stream.
static void write_line()
Writes the current line terminator to the standard output stream using the specified format informati...
bool redirect_standard_output() const noexcept
Gets a value that indicates whether the textual output of an application is written to the xtd::diagn...
const xtd::string & file_name() const noexcept
Gets the application or document to start.
bool use_shell_execute() const noexcept
Gets a value indicating whether to use the operating system shell to start the process.
std::istream & standard_output()
Gets a stream used to read the textual output of the application.
const xtd::diagnostics::process_start_info & start_info() const
Gets the properties to pass to the xtd::diagnostics::process::start() method of the xtd::diagnostics:...
bool start()
Starts (or reuses) the process resource that is specified by the xtd::diagnostics::process::start_inf...
process & wait_for_exit()
Instructs the xtd::diagnostics::process component to wait indefinitely for the associated process to ...
Provides access to local and remote processes and enables you to start and stop local system processe...
Definition process.h:49
Implements a xtd::io::text_reader that reads characters from a byte stream.
Definition stream_reader.h:28
#define block_scope_(...)
The specified expression is cleared automatically when the scope is ended.
Definition block_scope.h:25
The xtd::diagnostics namespace provides classes that allow you to interact with system processes,...
Definition assert_dialog_result.h:10
The xtd::io namespace contains types that allow reading and writing to files and data streams,...
Definition binary_reader.h:16
The xtd namespace contains all fundamental classes to access Hardware, Os, System,...
Definition xtd_about_box.h:10
Remarks
When a xtd::diagnostics::process writes text to its standard stream, that text is normally displayed on the console. By redirecting the xtd::diagnostics::process::standard_output stream, you can manipulate or suppress the output of a process. For example, you can filter the text, format it differently, or write the output to both the console and a designated log file.
Note
To use xtd::diagnostics::process::standard_output, you must set xtd::diagnostics::process_start_info::use_shell_execute to false, and you must set xtd::diagnostics::process_start_info::redirect_standard_output to true. Otherwise, reading from the xtd::diagnostics::process::standard_output stream throws an exception.
Remarks
The redirected xtd::diagnostics::process::standard_output stream can be read synchronously or asynchronously. Methods such as xtd::io::stream_reader::read, xtd::io::stream_reader::read_line, and xtd::io::stream_reader::read_to_end perform synchronous read operations on the output stream of the process. These synchronous read operations do not complete until the associated Process writes to its xtd::diagnostics::process::xtd::diagnostics::process::standard_output stream, or closes the stream.
In contrast, xtd::diagnostics::process::begin_output_read_line starts asynchronous read operations on the xtd::diagnostics::process::standard_output stream. This method enables a designated event handler for the stream output and immediately returns to the caller, which can perform other work while the stream output is directed to the event handler.
Synchronous read operations introduce a dependency between the caller reading from the xtd::diagnostics::process::standard_output stream and the child process writing to that stream. These dependencies can result in deadlock conditions. When the caller reads from the redirected stream of a child process, it is dependent on the child. The caller waits on the read operation until the child writes to the stream or closes the stream. When the child process writes enough data to fill its redirected stream, it is dependent on the parent. The child process waits on the next write operation until the parent reads from the full stream or closes the stream. The deadlock condition results when the caller and child process wait on each other to complete an operation, and neither can proceed. You can avoid deadlocks by evaluating dependencies between the caller and child process.
The last two examples in this section use the xtd::diagnostics:process::start method to launch an executable named Write500Lines.exe. The following example contains its source code.
#include <xtd/xtd>
using namespace xtd;
using namespace xtd::io;
auto main() -> int {
for (int ctr = 0; ctr < 500; ctr++)
console::write_line("Line {} of 500 written: {:P2}", ctr + 1, (ctr + 1)/500.0);
console::error << "\nSuccessfully wrote 500 lines.\n";
}
// The example displays the following output:
// The last 40 characters in the output stream are:
// ': 99.80%
// Line 500 of 500 written: 100.00%
// '
//
// Successfully wrote 500 lines.
static std::ostream error
Gets the error output stream. A std::basic_ostream<char_t> that represents the error output stream.
Definition console.h:42
The following example shows how to read from a redirected error stream and wait for the child process to exit. It avoids a deadlock condition by calling stream_reader(p.standard_error()).read_to_end() before p.wait_for_exit. A deadlock condition can result if the parent process calls p.wait_for_exit before stream_reader(p.standard_error()).read_to_end() and the child process writes enough text to fill the redirected stream. The parent process would wait indefinitely for the child process to exit. The child process would wait indefinitely for the parent to read from the full xtd::diagnostics::process::standard_error stream.
#include <xtd/xtd>
using namespace xtd;
using namespace xtd::diagnostics;
using namespace xtd::io;
auto main() -> int {
auto p = process();
p.start_info().use_shell_execute(false);
p.start_info().redirect_standard_error(true);
p.start_info().file_name("write_500_lines");
p.start();
// To avoid deadlocks, always read the output stream first and then wait.
string output = stream_reader(p.standard_error()).read_to_end();
p.wait_for_exit();
console::write_line("\nError stream: {}", output);
}
// The end of the output produced by the example includes the following:
// Error stream: Successfully wrote 500 lines.
process()
Initializes a new instance of the xtd::diagnostics::process class.
virtual xtd::string read_to_end()
Reads all characters from the current position to the end of the text_reader and returns them as one ...
@ p
The P key.
There is a similar issue when you read all text from both the standard output and standard error streams. The following example performs a read operation on both streams. It avoids the deadlock condition by performing asynchronous read operations on the xtd::diagnostics::process::standard_error stream. A deadlock condition results if the parent process calls stream_reader(p.standard_output()).read_to_end() followed by stream_reader(p.standard_error()).read_to_end() and the child process writes enough text to fill its error stream. The parent process would wait indefinitely for the child process to close its xtd::diagnostics::process::standard_output stream. The child process would wait indefinitely for the parent to read from the full xtd::diagnostics::process::standard_error stream.
#include <xtd/xtd>
using namespace xtd;
using namespace xtd::diagnostics;
using namespace xtd::io;
auto main() -> int {
auto p = process();
p.start_info().use_shell_execute(false);
p.start_info().redirect_standard_output(true);
string e_out;
p.start_info().redirect_standard_error(true);
p.error_data_received += [&](object& sender, const data_received_event_args& e) {
e_out += e.data();
};
p.start_info().file_name("write_500_lines");
p.start();
// To avoid deadlocks, always read the output stream first and then wait.
p.begin_error_read_line();
string output = stream_reader(p.standard_error()).read_to_end();
p.wait_for_exit();
console::write_line("\nError stream: {}", output);
}
// The example displays the following output:
// The last 40 characters in the output stream are:
// ': 99.80%
// Line 500 of 500 written: 100.00%
// '
//
// Error stream: Successfully wrote 500 lines.
Provides data for the xtd::diagnostics::process::output_data_received and xtd::diagnostics::process::...
Definition data_received_event_args.h:28
@ e
The E key.
You can use asynchronous read operations to avoid these dependencies and their deadlock potential. Alternately, you can avoid the deadlock condition by creating two threads and reading the output of each stream on a separate thread.
Note
You cannot mix asynchronous and synchronous read operations on a redirected stream. Once the redirected stream of a xtd::diagnostics::process is opened in either asynchronous or synchronous mode, all further read operations on that stream must be in the same mode. For example, do not follow xtd::diagnostics::process::begin_output_read_line with a call to xtd::io::stream_reader::read_line on the xtd::diagnostics::process::standard_output stream, or vice versa. However, you can read two different streams in different modes. For example, you can call xtd::diagnostics::process::begin_output_read_line and then call xtd::io::stream_reader::read_line for the xtd::diagnostics::process::standard_error stream.