[Win32utils-devel] Fw: re. win32-process

Daniel Berger Daniel.Berger at qwest.com
Tue Nov 21 11:07:46 EST 2006


Heesob Park wrote:
> Hi,
>
> 2006/11/21, Daniel Berger <djberg96 at yahoo.com 
> <mailto:djberg96 at yahoo.com>>:
>
>     Hi all,
>
>     Any ideas for the question below?  I know how to do this in theory
>     - make the 'inherit' flag true, and set the 'stdout' and 'stderr'
>     startf_flags hash options to something in the startup_info hash,
>     but I wasn't sure how to do this in practice.
>
>     It would be nice if the answer could be something like this:
>
>     require 'win32/process'
>
>     app_name = 'c:\ruby\bin\ruby "' + Dir.pwd + '/test.rb"'
>     my_out = $stdout.clone
>     my_err = $stderr.clone
>     my_out.reopen('NUL')
>     my_err.reopen('NUL')
>
>     Process.create(
>       :app_name => app_name,
>       :inherit  => true,
>       :creation_flags => Process::DETACHED_PROCESS,
>       :startup_info => {
>          :startf_flags => Process::STARTF_USESTDHANDLES,
>          :stdout => my_out,
>          :stderr => my_err
>       }
>     )
>
>     I think it would be neat if you could pass IO objects (or perhaps
>     a fileno) to :stdout, :stderr, and :stdin directly.  Any ideas on
>     how to do that?
>
>     Thanks,
>
>     Dan
>
>  
> Use _get_osfhandle function like this:
>  
>   :stdout => _get_osfhandle(my_out.to_i),
>   :stderr => _get_osfhandle(my_err.to_i),
>  
> Regards,
>  
> Park Heesob
Thanks, I couldn't remember the name of the function last night - too 
tired. ;)

I've added get_osfhandle to the Windows::Handle module (in windows-pr) 
in CVS.  Then I added this to the Process.create method:

# Automatically handle stdin, stdout and stderr as either IO objects
# or file descriptors.  This won't work for StringIO, however.
['stdin', 'stdout', 'stderr'].each{ |io|
   if si_hash[io]
      if si_hash[io].respond_to?(:fileno)
         handle = get_osfhandle(si_hash[io].fileno)
      else
         handle = get_osfhandle(si_hash[io])
      end
            
      if handle == INVALID_HANDLE_VALUE
         raise ProcessError, get_last_error
      end
            
      si_hash[io] = handle
   end
}

That seems to work fairly well.  The only quirk I noticed is that it 
doesn't seem to honor the append flag for the file descriptor:

# test.rb
5.times{ |i| puts "I: #{i}" }

# proc_test.rb
require 'win32/process'
app = 'c:\ruby\bin\ruby "' + Dir.pwd + '/test.rb"'

fh = File.open('test.txt', 'a')
Process.create(
   :app_name => app,
   :inherit  => true,
   :creation_flags => Process::DETACHED_PROCESS,
   :startup_info => {
      :startf_flags => Process::STARTF_USESTDHANDLES,
      :stdout => fh
   }
)
fh.close

Instead of appending to the test.txt file, it appears to simply 
overwrite it each time.  I can't remember if we discussed this in the 
past or not.  If there's no way to deal with it, then it's not a huge 
deal - I just need to document it.

What do you think?

Regards,

Dan

PS - Any way we could support StringIO as well?


More information about the win32utils-devel mailing list