Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

runproc.py 3.9KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. """runproc.py
  2. start a process with three inherited pipes.
  3. Try to write to and read from those.
  4. """
  5. import msvcrt
  6. import os
  7. import win32api
  8. import win32con
  9. import win32file
  10. import win32pipe
  11. import win32process
  12. import win32security
  13. class Process:
  14. def run(self, cmdline):
  15. # security attributes for pipes
  16. sAttrs = win32security.SECURITY_ATTRIBUTES()
  17. sAttrs.bInheritHandle = 1
  18. # create pipes
  19. hStdin_r, self.hStdin_w = win32pipe.CreatePipe(sAttrs, 0)
  20. self.hStdout_r, hStdout_w = win32pipe.CreatePipe(sAttrs, 0)
  21. self.hStderr_r, hStderr_w = win32pipe.CreatePipe(sAttrs, 0)
  22. # set the info structure for the new process.
  23. StartupInfo = win32process.STARTUPINFO()
  24. StartupInfo.hStdInput = hStdin_r
  25. StartupInfo.hStdOutput = hStdout_w
  26. StartupInfo.hStdError = hStderr_w
  27. StartupInfo.dwFlags = win32process.STARTF_USESTDHANDLES
  28. # Mark doesn't support wShowWindow yet.
  29. # StartupInfo.dwFlags = StartupInfo.dwFlags | win32process.STARTF_USESHOWWINDOW
  30. # StartupInfo.wShowWindow = win32con.SW_HIDE
  31. # Create new output read handles and the input write handle. Set
  32. # the inheritance properties to FALSE. Otherwise, the child inherits
  33. # the these handles; resulting in non-closeable handles to the pipes
  34. # being created.
  35. pid = win32api.GetCurrentProcess()
  36. tmp = win32api.DuplicateHandle(
  37. pid,
  38. self.hStdin_w,
  39. pid,
  40. 0,
  41. 0, # non-inheritable!!
  42. win32con.DUPLICATE_SAME_ACCESS,
  43. )
  44. # Close the inhertible version of the handle
  45. win32file.CloseHandle(self.hStdin_w)
  46. self.hStdin_w = tmp
  47. tmp = win32api.DuplicateHandle(
  48. pid,
  49. self.hStdout_r,
  50. pid,
  51. 0,
  52. 0, # non-inheritable!
  53. win32con.DUPLICATE_SAME_ACCESS,
  54. )
  55. # Close the inhertible version of the handle
  56. win32file.CloseHandle(self.hStdout_r)
  57. self.hStdout_r = tmp
  58. # start the process.
  59. hProcess, hThread, dwPid, dwTid = win32process.CreateProcess(
  60. None, # program
  61. cmdline, # command line
  62. None, # process security attributes
  63. None, # thread attributes
  64. 1, # inherit handles, or USESTDHANDLES won't work.
  65. # creation flags. Don't access the console.
  66. 0, # Don't need anything here.
  67. # If you're in a GUI app, you should use
  68. # CREATE_NEW_CONSOLE here, or any subprocesses
  69. # might fall victim to the problem described in:
  70. # KB article: Q156755, cmd.exe requires
  71. # an NT console in order to perform redirection..
  72. None, # no new environment
  73. None, # current directory (stay where we are)
  74. StartupInfo,
  75. )
  76. # normally, we would save the pid etc. here...
  77. # Child is launched. Close the parents copy of those pipe handles
  78. # that only the child should have open.
  79. # You need to make sure that no handles to the write end of the
  80. # output pipe are maintained in this process or else the pipe will
  81. # not close when the child process exits and the ReadFile will hang.
  82. win32file.CloseHandle(hStderr_w)
  83. win32file.CloseHandle(hStdout_w)
  84. win32file.CloseHandle(hStdin_r)
  85. self.stdin = os.fdopen(msvcrt.open_osfhandle(self.hStdin_w, 0), "wb")
  86. self.stdin.write("hmmmmm\r\n")
  87. self.stdin.flush()
  88. self.stdin.close()
  89. self.stdout = os.fdopen(msvcrt.open_osfhandle(self.hStdout_r, 0), "rb")
  90. print("Read on stdout: ", repr(self.stdout.read()))
  91. self.stderr = os.fdopen(msvcrt.open_osfhandle(self.hStderr_r, 0), "rb")
  92. print("Read on stderr: ", repr(self.stderr.read()))
  93. if __name__ == "__main__":
  94. p = Process()
  95. exe = win32api.GetModuleFileName(0)
  96. p.run(exe + " cat.py")
  97. # end of runproc.py