Output to non-console handles?
ysc3839 opened this issue · comments
In lxlaunch.cpp:203 it checks whether the output handle is a console handle. I wonder if it's possible to make it supports non-console handles?
발견했습니다..
영어로 뭐라 해야되나..
i solved (??)
if (GetFileType(inHandle) != FILE_TYPE_CHAR)
{
stdHandles.StdIn.Handle = (ULONG)inHandle;
stdHandles.StdIn.Pipe = true;
}else{
oldInCp = GetConsoleCP();
SetConsoleCP(CP_UTF8);
GetConsoleMode(inHandle, &oldInMode);
SetConsoleMode(inHandle, oldInMode &
~(ENABLE_INSERT_MODE |
ENABLE_ECHO_INPUT |
ENABLE_LINE_INPUT |
ENABLE_PROCESSED_INPUT) |
(ENABLE_VIRTUAL_TERMINAL_INPUT |
ENABLE_WINDOW_INPUT));
}
Doesn't work...
유감
I guess this is caused by two lxss processes running in a console window.
The redirection to non-lxss works well.
I do not know what 2 means, but it will be good for you.
hr = ((PLX_INSTANCE_V2)iLxInstance)->CreateLxProcess(
(PLX_INSTANCE_V2)iLxInstance,
imageFileName,
cmdCount,
cmdLine,
"C:\windows\system32;c:\windows",
currentDirectory,
2,
// LX_CREATE_PROCESS_PRINT_UPDATE_INFO_FLAG,
&stdHandles,
&consoleData2,
0,
&processHandle,
&serverHandle);
}
I think it's because lxss requires a console to output. In RS2 it handles console input and output, so there's no way to output to non-console handles.
What do you mean? 🤔
I have confirmed that it works well, but I am sorry that I can not show it.
So I'll show you the code.
//...skip
ULONG Flag = LX_CREATE_PROCESS_PRINT_UPDATE_INFO_FLAG;
//
// Get, and validate, the output handle
//
outHandle = GetStdHandle(STD_OUTPUT_HANDLE);
if (GetFileType(outHandle) != FILE_TYPE_CHAR)
{
stdHandles.StdOut.Pipe = true;
stdHandles.StdOut.Handle = HandleToULong(outHandle);
Flag = 2;
}
else {
//
// Switch to VT-100 Output Console
//
GetConsoleMode(outHandle, &oldOutMode);
SetConsoleMode(outHandle, oldOutMode |
DISABLE_NEWLINE_AUTO_RETURN |
0x4 |
ENABLE_PROCESSED_OUTPUT);
//
// Switch output to UTF-8
//
oldOutCp = GetConsoleOutputCP();
SetConsoleOutputCP(CP_UTF8);
}
//
// Get, and validate, the output handle
//
inHandle = GetStdHandle(STD_INPUT_HANDLE);
if (GetFileType(inHandle) != FILE_TYPE_CHAR)
{
stdHandles.StdIn.Handle = HandleToULong(inHandle);
stdHandles.StdIn.Pipe = true;
}
else {
//
// Switch to VT-100 Input Console
//
GetConsoleMode(inHandle, &oldInMode);
SetConsoleMode(inHandle, oldInMode &
~(ENABLE_INSERT_MODE |
ENABLE_ECHO_INPUT |
ENABLE_LINE_INPUT |
ENABLE_PROCESSED_INPUT) |
(ENABLE_VIRTUAL_TERMINAL_INPUT |
ENABLE_WINDOW_INPUT));
//
// Switch input to UTF-8
//
oldInCp = GetConsoleCP();
SetConsoleCP(CP_UTF8);
}
//...skip
hr = ((PLX_INSTANCE_V2)iLxInstance)->CreateLxProcess(
(PLX_INSTANCE_V2)iLxInstance,
imageFileName,
cmdCount,
cmdLine,
"C:\windows\system32;c:\windows",
currentDirectory,
Flag,
&stdHandles,
&consoleData2,
0,
&processHandle,
&serverHandle);
//...skip
@ionescu007 So you mean RS2 supports non-console handles? What about RS1?
@joshouamel Tested on 10.0.14393, still doesn't work...
My code: https://gist.github.com/ysc3839/078f3137ce5b5e8b3104ba5cbaa88d7b
Of course it will not work out. What about Anonymous pipes rather than named pipes? Two programs could not share a pipe. You do not have to wait if inhandle is in pipe mode at the end of the process.
waitArray[0] = UlongToHandle(processHandle);
waitArray[1] = GetStdHandle(STD_INPUT_HANDLE);
if(stdHandles.StdIn.Pipe)
WaitForSingleObject(waitArray[0], INFINITE);
else while (WaitForMultipleObjects(RTL_NUMBER_OF(waitArray),
waitArray,
FALSE,
INFINITE))
{
//
// Read the console input -- we only care about key pressses
//
assert(useRs2Logic == FALSE);
ReadConsoleInput(waitArray[1], &record, 1, &eventsRead);
if ((record.EventType == KEY_EVENT) &&
(record.Event.KeyEvent.bKeyDown != FALSE))
{
//
// Write into the Linux input pipe the character
//
WriteFile(inPipe,
&record.Event.KeyEvent.uChar.AsciiChar,
1,
&bytesWritten,
NULL);
}
}