2

I am executing Ironpython scripts from a Windows application that has an embedded Ironpython shell. I can launch the application, load a script and start their execution from a (.bat) file. I would like to close the application once the test scripts finish. However, the application vendor has not provided the functionality to close the application programmatically.

My first thought was to use a PIPE to monitor a specific string which will terminate the subprocess. My test script opens up a form which gets populated with data needed for testing. There are other complications which I am not sure how to handle in printing to the PIPE. Any printing goes directly to the application's shell window.

The method I am pursuing is to close the application by making the application's window active. Below is my code which is based on
Python's pywin32 extension

import ctypes
import re

EnumWindows = ctypes.windll.user32.EnumWindows
EnumWindowsProc = ctypes.WINFUNCTYPE(ctypes.c_bool, ctypes.POINTER(ctypes.c_int), ctypes.POINTER(ctypes.c_int))
GetWindowText = ctypes.windll.user32.GetWindowTextW
GetWindowTextLength = ctypes.windll.user32.GetWindowTextLengthW
IsWindowVisible = ctypes.windll.user32.IsWindowVisible

class my_test():

    def __init__ (self):
        """Constructor"""

        self._handle = None
        self.wildcard = "Program name"
        self.titles = []


    def foreach_window(self, hwnd, lParam):
        '''Pass to EnumWindows() to check all the opened windows'''

        if IsWindowVisible(hwnd):
            length = GetWindowTextLength(hwnd)
            #print 'length', length
            buff = ctypes.create_unicode_buffer(1024)
            #buff = ctypes.create_unicode_buffer(length + 1)
            #print 'buff', buff       

            GetWindowText(hwnd, buff, length + 1)
            self.titles.append(buff.value)

            if re.match(self.wildcard, str(buff.value)) != None:
                self._handle = hwnd
                print 'self._handle', self._handle
                print 'str(buff.value)', str(buff.value)

        return True

    def find_window(self):
        EnumWindows(EnumWindowsProc(self.foreach_window), 0)

    def set_foreground(self):
        """put the window in the foreground"""        
        ctypes.windll.user32.SetActiveWindow(self._handle)
        ctypes.windll.user32.SetForegroundWindow(self._handle)
        ctypes.windll.user32.PostMessage(self._handle, win32con.WM_CLOSE, 0, 0)

def main():
    w = my_test()
    w.find_window()
    w.set_foreground()

I found another discussion on closing application (I think using pywin32 extensions) 2. The author refers to win32process and win32gui. Do these modules have a ctypes equivalent?

I added the following lines to the code.

SendMessage = ctypes.windll.user32.SendMessageW
WM_SYSCOMMAND = ctypes.c_int(0x0112)
SC_CLOSE = ctypes.c_int(0xF060) 

Replaced line

ctypes.windll.user32.PostMessage(self._handle, win32con.WM_CLOSE, 0, 0)

with

SendMessage(my_window,  WM_SYSCOMMAND, SC_CLOSE, 0)

This works as long as I execute this script in a separate IronPython shell.

taskkill did the trick, see

https://stackoverflow.com/a/6984331/2556944

Community
  • 1
  • 1
cjbust
  • 123
  • 2
  • 3
  • 10

0 Answers0