class_docstr: Runs a shell command in a 'with' context.
  
  This implementation is Win32-specific.
  
  Example:
      # Runs the command interactively with default console stdin/stdout
      with ShellCommandController('python -i') as scc:
          scc.run()
  
      # Runs the command using the provided functions for stdin/stdout
      def my_stdout_func(s):
          # print or save the string 's'
          write_to_stdout(s)
      def my_stdin_func():
          # If input is available, return it as a string.
          if input_available():
              return get_input()
          # If no input available, return None after a short delay to
          # keep from blocking.
          else:
              time.sleep(0.01)
              return None
    
      with ShellCommandController('python -i') as scc:
          scc.run(my_stdout_func, my_stdin_func)
code: def _stdin_thread(self, handle, hprocess, func, stdout_func):
      exitCode = DWORD()
      bytesWritten = DWORD(0)
      while True:
          # print("stdin thread loop start")
          # Get the input string (may be bytes or unicode)
          data = func()
  
          # None signals to poll whether the process has exited
          if data is None:
              # print("checking for process completion")
              if not GetExitCodeProcess(
                  hprocess, ctypes.byref(exitCode)
              ):
                  raise ctypes.WinError()
              if exitCode.value != STILL_ACTIVE:
                  return
              # TESTING: Does zero-sized writefile help?
              if not WriteFile(
                  handle, "", 0, ctypes.byref(bytesWritten), None
              ):
                  raise ctypes.WinError()
              continue
          # print("\nGot str %s\n" % repr(data), file=sys.stderr)
  
          # Encode the string to the console encoding
          if isinstance(data, unicode):  # FIXME: Python3
              data = data.encode("utf_8")
  
          # What we have now must be a string of bytes
          if not isinstance(data, str):  # FIXME: Python3
              raise RuntimeError("internal stdin function string error")
  
          # An empty string signals EOF
          if len(data) == 0:
              return
  
          # In a windows console, sometimes the input is echoed,
          # but sometimes not. How do we determine when to do this?
          stdout_func(data)
          # WriteFile may not accept all the data at once.
          # Loop until everything is processed
          while len(data) != 0:
              # print("Calling writefile")
              if not WriteFile(
                  handle,
                  data,
                  len(data),
                  ctypes.byref(bytesWritten),
                  None,
              ):
                  # This occurs at exit
                  if GetLastError() == ERROR_NO_DATA:
                      return
                  raise ctypes.WinError()
              # print("Called writefile")
              data = data[bytesWritten.value :]
  
imports: from __future__ import print_function
  import os, sys, threading
  import ctypes, msvcrt
  from .None import py3compat
  from ctypes import POINTER
  from ctypes.wintypes import HANDLE, HLOCAL, LPVOID, WORD, DWORD, BOOL, ULONG, LPCWSTR
label_desc: Use image node_id 3 for calling the Win32ShellCommandController obj's underlying member method code with example usage: obj._stdin_thread(handle, hprocess, func, stdout_func) without return types