Terminate an external applicationTag(s): WinAPI/Registry WinAPI/Registry


Using VBScript
This will immediately close any running instance of Notepad.
OleObject wsh
integer  li_rc

wsh = CREATE OleObject
wsh.ConnectToNewObject( "MSScriptControl.ScriptControl" )
wsh.language = "vbscript"
wsh.AddCode('function terminatenotepad() ~n ' + &
 'strComputer = "." ~n ' + &
 'Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2") ~n ' + &
 'Set colItems = objWMIService.ExecQuery("Select * from Win32_Process where name = ~'notepad.exe~'") ~n ' + &
 'For Each objItem in colItems ~n ' + &
 '     objItem.Terminate ~n ' + &
 'Next ~n ' + &
 'end function ~n ' )
wsh.executestatement('terminatenotepad()')
wsh.DisconnectObject()
DESTROY wsh
Replace notepad.exe with the executable name that you want to close.
Using WinAPI with the class name
This will close a running Notepad but will ask to save any unsaved document. We are using the WinAPI to retrieve an handle and then we send the event WM_CLOSE to the object associated with the handle.
[local external function declaration]
// PB10
FUNCTION ulong FindWindow(ref string  classname, ref string   windowname) &
LIBRARY "user32.dll" &
ALIAS FOR "FindWindowA;ansi"

// or PB10  alternate declaration
// FUNCTION ulong FindWindow (ref string  classname, ref string  windowname) &
// LIBRARY "user32.dll" &
// ALIAS FOR "FindWindowW"


// or PB9
// FUNCTION ulong FindWindow(ref string  classname, ref string   windowname) &
// LIBRARY "user32.dll" &
// ALIAS FOR "FindWindowA"

[powerscript]

ulong hWnd
string ls_title
string ls_class

ls_class = "Notepad"
SetNull(ls_name)

hWnd = FindWindow(ls_class, ls_title)

IF NOT IsNull(hWnd) THEN
    // WM_CLOSE = &H10 == 16
    send(hwnd, 16, 0, 0)
END IF
You need a special tool to detect the class name. A well known tool to detect the class name is SPY++, you may already have it (since it was included with PB Entreprise). Or you can download a free one, WinID at http://www.softpedia.com/get/Programming/Debuggers-Decompilers- Dissasemblers/WinID.shtml

To close an application builded with Powerbuilder, you need a class name, it's difficult because the class name is not always the same with new PB release. With PB10, it's FNWND3100 so for PB11 it maybe FNWND3110 ...

PB9ls_class = "FNWND390"
PB10 ls_class = "FNWND3100"
PB11 ls_class = "FNWND3110" // ??

You may need to use the next technique if you want to close another Powerbuilder application and not close yourself at the same time !

Using WinAPI with a window title
Another possibility is to use the window title with the FindWindow API to search for the handle. This is ok if your title is static and known in advance.
[local external function declaration]
// PB10
FUNCTION ulong FindWindow(ref string  classname, ref string   windowname)  LIBRARY "user32.dll" &
ALIAS FOR "FindWindowA;ansi"

// or PB10  alternate declaration
// FUNCTION ulong FindWindow (ref string  classname, ref string  windowname) &
// LIBRARY "user32.dll" &
// ALIAS FOR "FindWindowW"


//  or PB9
// FUNCTION ulong FindWindow(ref string  classname, ref string   windowname)  &
// LIBRARY "user32.dll" &
// ALIAS FOR "FindWindowA"

[powerscript]

ulong hWnd
string ls_title
string ls_class

ls_name = "Untitled - Notepad"
SetNull(ls_class)

hWnd = FindWindow(ls_class, ls_title)

IF NOT IsNull(hWnd) THEN
    // WM_CLOSE = &H10
    send(hwnd, 16, 0, 0)
END IF
Note : It's possible to search the handle with the class name and the window title.
[powerscript]

ulong hWnd
string ls_title
string ls_class

ls_name = "Untitled - Notepad"
ls_class= "Notepad"

hWnd = FindWindow(ls_class, ls_title)

IF NOT IsNull(hWnd) THEN
    // WM_CLOSE = &H10
    send(hwnd, 16, 0, 0)
END IF

blog comments powered by Disqus