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)
docstr: Runs the process, using the provided functions for I/O.
  
  The function stdin_func should return strings whenever a
  character or characters become available.
  The functions stdout_func and stderr_func are called whenever
  something is printed to stdout or stderr, respectively.
  These functions are called from different threads (but not
  concurrently, because of the GIL).
docstr_tok: ["Runs","the","process",",","using","the","provided","functions","for","I\/O",".","The","function","stdin_func","should","return","strings","whenever","a","character","or","characters","become","available",".","The","functions","stdout_func","and","stderr_func","are","called","whenever","something","is","printed","to","stdout","or","stderr",",","respectively",".","These","functions","are","called","from","different","threads","(","but","not","concurrently",",","because","of","the","GIL",")","."]
code: def run(self, stdout_func=None, stdin_func=None, stderr_func=None):
      """Runs the process, using the provided functions for I/O.
  
      The function stdin_func should return strings whenever a
      character or characters become available.
      The functions stdout_func and stderr_func are called whenever
      something is printed to stdout or stderr, respectively.
      These functions are called from different threads (but not
      concurrently, because of the GIL).
      """
      if (
          stdout_func is None
          and stdin_func is None
          and stderr_func is None
      ):
          return self._run_stdio()
  
      if stderr_func is not None and self.mergeout:
          raise RuntimeError(
              "Shell command was initiated with "
              "merged stdin/stdout, but a separate stderr_func "
              "was provided to the run() method"
          )
  
      # Create a thread for each input/output handle
      stdin_thread = None
      threads = []
      if stdin_func:
          stdin_thread = threading.Thread(
              target=self._stdin_thread,
              args=(
                  self.hstdin,
                  self.piProcInfo.hProcess,
                  stdin_func,
                  stdout_func,
              ),
          )
      threads.append(
          threading.Thread(
              target=self._stdout_thread,
              args=(self.hstdout, stdout_func),
          )
      )
      if not self.mergeout:
          if stderr_func is None:
              stderr_func = stdout_func
          threads.append(
              threading.Thread(
                  target=self._stdout_thread,
                  args=(self.hstderr, stderr_func),
              )
          )
      # Start the I/O threads and the process
      if ResumeThread(self.piProcInfo.hThread) == 0xFFFFFFFF:
          raise ctypes.WinError()
      if stdin_thread is not None:
          stdin_thread.start()
      for thread in threads:
          thread.start()
      # Wait for the process to complete
      if (
          WaitForSingleObject(self.piProcInfo.hProcess, INFINITE)
          == WAIT_FAILED
      ):
          raise ctypes.WinError()
      # Wait for the I/O threads to complete
      for thread in threads:
          thread.join()
  
      # Wait for the stdin thread to complete
      if stdin_thread is not None:
          stdin_thread.join()
  
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 5 for calling the Win32ShellCommandController obj's underlying member method code with example usage: obj.run(stdout_func, stdin_func, stderr_func) and returns: self