Hello, I'm using (and have tried both) node 0.10.3x and 0.11.x (and the node bleeding edge) and have an issue i'm hoping someone can shed some light on.
I'm embedding node into a Win32 GUI app (that is to say /Subsystem:Windows and wWinMain, rather than the default /subsystem:console). Windows applications do not setup a proper stderr, stdin, stdout handles. When node::Load() attempts to run, the application exits with either code 1 (for node 0.11) or code 8 (for node 0.10). I've traced the problem down. - It starts with libuv win/handle.c <https://github.com/libuv/libuv/blob/c0716b3d9f89e3557a482ce499e7abc8db686418/src/win/handle.c#L56> in the function uv_guess_handle (line 56) that returns a FILE_TYPE_UNKNOWN for the file descriptor 1 or 2 (stdout, or stderr) if the subsystem is compiled as "Windows". - This is called when node::Load runs, specifically in, src/node.js the function createWritableStdioStream <https://github.com/joyent/node/blob/90d1147b8be188cb53de3d5faea2818310509cf9/src/node.js#L483> (line 483) - The createWritableStdioStream causes an error to be thrown thats caught by node.cc <https://github.com/joyent/node/blob/master/src/node.cc#L2182> (line 2182) - The FatalException exits the application, since we're in a windows GUI application, we don't see this, as its printed to stderr.. which doesn't exist (making it incredibly difficult to track down). - *Other related files that are used in the stack trace, but does not seem relevant: tty_wrap (line 89) <https://github.com/joyent/node/blob/a054f8eb29561873f0ae678e579d99f690d3032d/src/tty_wrap.cc#L89> * I've tried a few solutions but to no success. 1. Create a Windows console buffer when acting like a GUI app, this allows you to capture stdin/stdout for application running as a GUI. Unfortunately since lib win/handle.c (line 56) uses the low-level file descriptor and not the stdin/stdout stream, this has no effect as the console buffer simply replaced the stdin/stdout global streams, not the 0 & 1 FD descriptors. 2. Tried redirecting stdin, stdout, stderr using named pipes with CreateNamedPipe. This also had no effect for the same reason as #1. 3. Tried reopening the stream to re-assign them, this, no effect, see above. 4. Looked into hiding the console window and just compiling with /subsystem:console, however this causes a "flicker" when the app loads, but does successfully fix the issue. 5. Tried using AttachConsole to a "faked" child processes' console, the child process is a dummy process that is created with CreateProcess with the console attribute hidden. This "sort of" worked, but caused halting problems as the stdout/stdin are themselves unable to create a stream buffer for some reason. 6. Tried simply closing or opening the low-level fd stdout/stderr; however this had no effect and threw assertion errors from Windows. About to give up, I thought that SOMEONE, SOMEWHERE must have fixed this issue. I looked at applications that use node in a GUI app, and found two solutions: 1. Node-webkit modifies node.js to create dummy handles for stdio if its on win32. This isn't optimal, as i'd like to be able to only force the dummy handles for stdin/stdout/stderr if there really isn't a console available. 2. Atom and others seem to take the approach of second process launches, which creates a second process (of themselves) the first launched with a subsystem:windows, then relaunched with STARTUPINFO on CreateProcess set to hide the console (but launched as a console application). This isn't an optimal solution either, as I stated in #5 above, there are corner cases where the system cannot create a std stream but can deliver a valid file descriptor for the stream (it causes assertion errors in windows __open_oshandle, unsure why) Although it does seem to work for 95% of the use cases i've seen. For obvious reason (e.g., when running as a GUI) I do not have any use for standard in/outs, the optimal fix would be to create dummy stream handles on node::Load() for these instances (similar to node-webkit) but allow it to be a configurable option and not-by-default. *TL;DR: Node fails with no workaround if it can't find stdin/stdout, like in a GUI app. * *My first question: *Does anyone know of another alternate way of getting this to work that I haven't tried? I'd rather not submit a patch nor modify the node code as its upstream? *My second question: *If I submit a patch for node to help alleviate these issues, would creating dummy stdin/stdout/stderr be the best solution, is there alternate approaches recommended if I need to modify node? Thanks, Trevor Linton -- Job board: http://jobs.nodejs.org/ New group rules: https://gist.github.com/othiym23/9886289#file-moderation-policy-md Old group rules: https://github.com/joyent/node/wiki/Mailing-List-Posting-Guidelines --- You received this message because you are subscribed to the Google Groups "nodejs" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/nodejs/97ecfc46-50fc-43ae-921d-ba7b5019a48a%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
