[Tkinter-discuss] Okay,
this one really has me baffled --KeyboardInterrupt signal not working!
Stewart Midwinter
stewart.midwinter at gmail.com
Wed Apr 20 22:06:35 CEST 2005
Jared, maybe I've missed part of the conversation, but instead of
running an os.system command to start your process, how about using a
call to win32file's process creation? That way you can get a process
handle that will continue to exist only so long as the process is
alive. you can monitor for its continued existence. If you need to
kill the process, first check the handle, then kill using the PID.
you said you had problems getting access to the child process, but I
wonder if that's due to the fact that you are using an os.system
command to start the initial process. Just a thought.
Anyway, here's some code that starts a process:
def createProcess(self, file, args, env, name, logFilename,
currentDirectory, hide):
'''Start up a process to run some task, so that control is
returned to Scenario Manager immediately.
"file" is the name of the batch file to be run in the
process (e.g. "diagram" > diagram.bat)
"args" is a string containing any command-line arguments to
be passed to the batch file
"env" is an optional environment variable
"name" is an optional name for the process
"logFilename" is an optional log file name
"currentDirectory" is an optional specification of the
directory to be run in
'''
fname = self.createProcess.__name__
self.__lock = threading.Lock()
self.__terminationEvent = threading.Event()
file = os.path.normpath(file)
if not os.path.splitext(file)[1]:
file = file + '.exe'
if not os.path.isabs(file):
# Windows NT seems to want a full path
paths = string.split(self.getFromEnv('PATH', env, []),os.pathsep)
for path in paths:
fullPath = os.path.join(path, file)
if os.path.isfile(fullPath):
file = fullPath
break
args = file+' '+args
if self.debug: print 'args ',args
self._hideWindow = 0 # was 1
self.__fileSecurity = pywintypes.SECURITY_ATTRIBUTES()
self.__fileSecurity.bInheritHandle = pywintypes.TRUE
self.__inputFile = win32file.CreateFile(
_nullFilename, win32file.GENERIC_READ,
win32file.FILE_SHARE_READ , self.__fileSecurity,
win32file.OPEN_EXISTING, win32file.FILE_ATTRIBUTE_NORMAL, 0)
startupInfo = win32process.STARTUPINFO()
#print 'log ',logFilename
if logFilename:
logfile = win32file.CreateFile(
logFilename, win32file.GENERIC_WRITE | win32file.GENERIC_READ,
win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE,
self.__fileSecurity, win32file.CREATE_ALWAYS, 0, 0)
startupInfo.hStdInput = self.__inputFile
startupInfo.hStdOutput = int(logfile)
startupInfo.hStdError = int(logfile)
startupInfo.dwFlags = win32process.STARTF_USESTDHANDLES
if self._hideWindow:
startupInfo.dwFlags = (startupInfo.dwFlags |
win32process.STARTF_USESHOWWINDOW)
else:
logfile = None
if currentDirectory:
directoryMessage = ' in %s' % currentDirectory
else:
directoryMessage = ''
try:
try:
flags = 0
# Session Cancel will kill the required processes.
if hide == 0:
flags = flags | win32process.DETACHED_PROCESS
msg = 'now starting process with file %s & args %s &
env %s & directory %s' % (str(file), str(args), str(env),
str(currentDirectory))
if self.debug: self.write_debug(fname, msg)
self.__processInfo = win32process.CreateProcess(
file, args , None, None,
pywintypes.TRUE, flags, env, currentDirectory, startupInfo)
except win32process.error, value:
raise win32process.error(
value.args + (file, currentDirectory))
finally:
if logfile is not None:
logfile.Close()
# Close the thread handle, we don't need it
self.__processInfo[1].Close()
# createProcess() must return the new process id
print 'process %s has the following info:\n - handle %s,
thread %s, pid %s, threadID %s ' % \
(name,
str(self.__processInfo[0]),
str(self.__processInfo[1]),
str(self.__processInfo[2]),
str(self.__processInfo[3]) )
return self.__processInfo
And here's an excerpt from a method that calls that method to start a
process. In this case, we are running an executable called tui.exe:
...
info = self.createProcess('tui',
msg,
env=None,
name = 'status-%s' % (self.scenario_name),
logFilename=None,
currentDirectory=os.path.join(pwPythonHome,'sm'),
hide=0)
#we care about the handle, the pid and maybe the threadID
self.statusHandle, statusThread, self.statusPid,
self.statusThreadID = info
self.handles.append(self.statusHandle)
msg = 'Status pid is %i' % self.statusPid
And here's how I cancel a process:
def cancel(self):
'''Cancel the execution of a process'''
fname = self.cancel.__name__
self.__paused = 'false'
self.run_state = 'false'
msg = 'trying to stop a process with self.__paused state= '
msg = '%s %s and self.run_state= %s and process PID %s' %
(msg, self.__paused, self.run_state, str(self.statusPid))
if self.debug: self.write_debug(fname, msg)
self.executeLogging("Stop RUNNING")
if self.statusPid is not None:
#someone might have already closed the status window
cmd = 'kill %s' % str(self.statusPid)
end1 = os.path.join(pwPipeworksHome, 'bin', cmd)
if self.debug: print 'kill status window,', cmd
os.system(end1)
hope this helps.
--
Stewart Midwinter
stewart at midwinter.ca
stewart.midwinter at gmail.com
Skype: midtoad
More information about the Tkinter-discuss
mailing list