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.

Reply via email to