Thread overview
Redirecting standard streams in Windows
Jul 18, 2023
Alexander Zhirov
Jul 18, 2023
Adam D Ruppe
Jul 18, 2023
Alexander Zhirov
Jul 18, 2023
Alexander Zhirov
Jul 18, 2023
Alexander Zhirov
Jul 19, 2023
Adam D Ruppe
Jul 19, 2023
Alexander Zhirov
July 18, 2023

I'm trying to redirect unicode in the windows console, but when redirecting, empty files are created. If i do it without redirects, then the text is displayed correctly in the console:

import core.sys.windows.windows;
import std.stdio;

void main() {
    wstring str = "Just text...";
    HANDLE h_stderr = GetStdHandle(STD_ERROR_HANDLE);
    HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
    WriteConsoleW(h_stderr, str.ptr, cast(DWORD)str.length, NULL, NULL);
    WriteConsoleW(h_stdout, str.ptr, cast(DWORD)str.length, NULL, NULL);
}
.\app.exe 1> stdout.txt 2> stderr.txt
July 18, 2023
On Tuesday, 18 July 2023 at 21:31:54 UTC, Alexander Zhirov wrote:
>     HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
>     WriteConsoleW(h_stderr, str.ptr, cast(DWORD)str.length, NULL, NULL);


If you checked the return value of this call, you'd find it fails since WriteConsole only works if the output is, in fact, a console.

You need to use WriteFile when it is redirected, which you can detect with GetFileType to see if it is a character device or not.
July 18, 2023

On Tuesday, 18 July 2023 at 22:09:40 UTC, Adam D Ruppe wrote:

>

On Tuesday, 18 July 2023 at 21:31:54 UTC, Alexander Zhirov wrote:

>
HANDLE h_stdout = GetStdHandle(STD_OUTPUT_HANDLE);
WriteConsoleW(h_stderr, str.ptr, cast(DWORD)str.length, NULL, NULL);

If you checked the return value of this call, you'd find it fails since WriteConsole only works if the output is, in fact, a console.

You need to use WriteFile when it is redirected, which you can detect with GetFileType to see if it is a character device or not.

Just found this on the net. Hmm... I didn't know that Windows has its own nuances in working with threads. Thanks for the tip.

July 18, 2023

On Tuesday, 18 July 2023 at 22:12:17 UTC, Alexander Zhirov wrote:

>

with threads

streams*

July 18, 2023

On Tuesday, 18 July 2023 at 22:09:40 UTC, Adam D Ruppe wrote:

>

You need to use WriteFile when it is redirected, which you can detect with GetFileType to see if it is a character device or not.

The redirection issue has been resolved. Another one has now emerged. Since I have unicode, I need to write 2 bytes each, which is exactly what happens. In this regard, incorrect output to the file. How to convert it otherwise? Or does it not depend on the output?

import core.sys.windows.windows;
import std.stdio;
import std.utf;

void main() {
    wstring str = "Это тестовый текст";
    HANDLE h_stderr = GetStdHandle(STD_ERROR_HANDLE);
    switch (GetFileType(h_stderr)) {
        case FILE_TYPE_CHAR:
            WriteConsoleW(h_stderr, str.ptr, cast(DWORD)str.length, NULL, NULL);
            break;
        case FILE_TYPE_PIPE:
            auto utf_str = str.toUTF8;
            WriteFile(h_stderr, utf_str.ptr, cast(DWORD)utf_str.length, NULL, NULL);
            break;
        default:
    }
}

output:

PS C:\dlang\test> dmd.exe .\app.d
PS C:\dlang\test> .\app.exe
Это тестовый текст
PS C:\dlang\test> .\app.exe 2> .\stderr.txt
PS C:\dlang\test> cat .\stderr.txt
.\app.exe : ╨н╤В╨╛ ╤В╨╡╤Б╤В╨╛╨▓╤Л╨╣ ╤В╨╡╨║╤Б╤В
строка:1 знак:1
+ .\app.exe 2> .\stderr.txt
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (╨н╤В╨╛ ╤В╨╡╤Б╤В╨╛╨▓╤Л╨╣ ╤В╨╡╨║╤Б╤В:String) [], RemoteException
    + FullyQualifiedErrorId : NativeCommandError


July 19, 2023
On Tuesday, 18 July 2023 at 23:52:06 UTC, Alexander Zhirov wrote:
> PS C:\dlang\test> cat .\stderr.txt

How does the cat program know what the encoding of the file is?

Try opening it in notepad or something and specifying the encoding. I betcha it is perfectly fine.
July 19, 2023

On Wednesday, 19 July 2023 at 00:13:04 UTC, Adam D Ruppe wrote:

>

How does the cat program know what the encoding of the file is?

Try opening it in notepad or something and specifying the encoding. I betcha it is perfectly fine.

Strange. Everything works correctly on the command line. And the file redirection works and 2>&1 works. But in PowerShell it gives errors. Moreover, PowerShell reacts to FILE_TYPE_PIPE, and CMD reacts to FILE_TYPE_DISK.