REBOL 3.0

Comments on: Stdio: a note about redirection in Windows

Carl Sassenrath, CTO
REBOL Technologies
27-Oct-2009 4:14 GMT

Article #0282
Main page || Index || Prior Article [0281] || Next Article [0283] || 11 Comments || Send feedback

Windows stdio redirection works in A93, but there are some things to know:

  1. In R3 the redirected stdin and stdout streams are UTF-8 encoded.
  2. In R3 the default console window is Unicode wide-char encoded.
  3. Do not mix the two modes.

For example, from a Command Prompt window, you can redirect output, or input and output:

> r3 -q test.r >output.txt

> r3 -q test.r <input.txt >output.txt

But, if you only redirect input:

> r3 -q test.r <input.txt

you're going to see a window pop up to handle any output. I've not found any way to solve this problem in Windows, nor do I find any information about it on the web. So, my advice is to redirect output as well.

Why?

The problem here comes from the fact that when running from a Command Prompt window, the handle returned by:

GetStdHandle(STD_OUTPUT_HANDLE)

is not valid for WriteFile(). Why? I cannot say. I researched it, but found no good explanation.

Of course, it's problematic anyway because you can't write UTF-8 to just any device in Windows. Windows is based on wide-char Unicode.

However, if you find the solution to this problem, let me know.

11 Comments

Comments:

-pekr-
27-Oct-2009 5:03:18
As per MSDN description, using StdHandle output should be possible to use in Read/WriteFile() funcs?

Handles returned by GetStdHandle can be used by applications that need to read from or write to the console. When a console is created, the standard input handle is a handle to the console's input buffer, and the standard output and standard error handles are handles of the console's active screen buffer. These handles can be used by the ReadFile and WriteFile functions, or by any of the console functions that access the console input buffer or a screen buffer (for example, the ReadConsoleInput, WriteConsole, or GetConsoleScreenBufferInfo functions).
Carl Sassenrath
27-Oct-2009 14:04:46
Of course... that's well documented, but does not work unless a console is created, e.g. AllocConsole(). Want proof? Compile the code below as an Win32 app (not console app), then try it from a command prompt shell.

int APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     int       nCmdShow)
{
	HANDLE out;
	DWORD n;
	out = GetStdHandle(STD_OUTPUT_HANDLE);
	if (WriteFile(out, "test\n", 5, &n, 0) == 0)
		MessageBox(0, "Pekr, it does not work", "Failed", MB_OK);
	return 0;
}

If you are running in a command prompt shell, you often do not want a console window to pop up. You want to run like a shell script.

The way we did this in R2 was ugly, IMO. We had to switch I/O from the Win32 API to the Clib API. We did this via the internal functions _open_osfhandle() and _fdopen(), reassigned stdin and stdout, and then used C I/O functions.

It seems to me that this should be unnecessary. Within the Clib I must assume that the Win32 API is being used. We would like to use that method directly, because that's how R3 does I/O.

deglingo
27-Oct-2009 18:23:04
Just passing by, having maybe a silly comment...And, it's not possible to set the standard output to the desired console using the SetStdHandle function before calling the GetStdHandle function ? Too obvious to be a good answer !
-pekr-
28-Oct-2009 14:52:49
Well, I am not really skilled in C, and pity others don't contribute here. I tried the code, and of course you are right. I tried to replace the function by WriteConsole one, but it does not output anything.

I found following article, maybe there will be some pointers:

http://www.halcyon.com/~ast/dload/guicon.htm

There is some talk about using _open_osfhandle(), but really dunno if it can help :-)

-pekr-
28-Oct-2009 15:36:04
I also wonder - how do Perl, Python, Ruby etc. aproach this problem?
Carl Sassenrath
28-Oct-2009 18:31:18
I've found a way to write to the CP, but it's asynchronous because R3 runs as a separate process, and there's nothing to tell the CP to wait for completion. So, that's a problem.

Various links of interest:

*Some main concepts: msdn.microsoft.com/en-us/library/ms971319.aspx

*Code ideas found here: src.chromium.org/viewvc/chrome/trunk/src/base/process_util_win.cc?view=markup&pathrev=30220

*Not what we want: support.microsoft.com/kb/105305 (This provides stdin to clib funcs, we don't need that.)

-pekr-
29-Oct-2009 1:38:37
Some answers from MS tech guy also here:

http://bytes.com/topic/net/answers/665637-win32-windows-application-outputting-command-prompt-if-console-program-how

He basically confirms, that when in Windows mode, console is async and proposes the way of how to possibly deal with it ...

-pekr-
29-Oct-2009 11:51:34
Taken from CodeProjects related article:

"The Windows GUI development doesn't conveniently support the access to cout, cerr, stdout, or stderr. It may be difficult to obtain these under direct control of the window program. At least there exist some tricks to obtain the information if really needed."

*www.codeproject.com/KB/cpp/EditBin.aspx

Following link collects some links for the topic:

*simplesamples.info/Windows/Redirection.php

Is the answer in using pipes? Following KB article linked also in above link

*support.microsoft.com/?id=190351

Well, I think I will stop here with my suggestions. While trying to be helpful, I expected more community input, at least by those, who are really and deeply familiar with C ...

Carl Sassenrath
29-Oct-2009 14:29:33
Pekr, good links. This one sums it up pretty well:

http://blogs.msdn.com/junfeng/archive/2004/02/06/68531.aspx

In other words, Win32 is defective in this regard. As an OS guy I'm pretty sure this problem is historic. In other words it was not an MS design decision, it's the result of the progression over time from MSDOS, to Win, to Win32. We cannot fix it.

However, it might be possible to distribute two versions of REBOL, one for GUI one for CON, or perhaps even a PRO package like the existing SDK that includes two launchers and one DLL. (Good for HOST and EMBED modes too.)

Of course, for most everyone, we want to stick with the REBOL goal of providing a single EXE that requires no other files. That would be the standard download.

Regarding other developers not making suggestions... I think very few users really require operation from the console "Command Prompt" (remember, REBOL can still open its own Con window, even from the GUI exe.) Now that the R3 EXE handles redirection, that solves most of the needs that someone would want.

Maxim Olivier-Adlhoch
30-Oct-2009 1:39:15
just having the option to run as shell or win GUI using two different .exe is ok.

python does it exactly like this and has the same problem... there is a windows version in which any call to printf will actually crash python!

so we are even a bit better than they so far (unless they've addressed it)

I needed the console version two years ago for a client application running as system commands, and actually had trouble using rebol because of this.

now at least, when faced with the same issue, technically-minded people will just have to choose an alternative which addresses this windows shortcoming when it presents itself.

-pekr-
30-Oct-2009 2:21:51
Someone should send a postcard to Redmond, with big ironic grin - Hello, I am your properly working GUI console ;-)

Post a Comment:

You can post a comment here. Keep it on-topic.

Name:

Blog id:

R3-0282


Comment:


 Note: HTML tags allowed for: b i u li ol ul font span div a p br pre tt blockquote
 
 

This is a technical blog related to the above topic. We reserve the right to remove comments that are off-topic, irrelevant links, advertisements, spams, personal attacks, politics, religion, etc.

REBOL 3.0
Updated 22-Jul-2017 - Edit - Copyright REBOL Technologies - REBOL.net