how to call killprogram()?

Just starting out? Need help? Post your questions and find answers here.
Klonk
Enthusiast
Enthusiast
Posts: 173
Joined: Tue Jul 13, 2004 2:17 pm

Post by Klonk »

Yes sorry, at my first try i forgot or did not use the flag #PB_Program_Open. As I used it I was able to kill the program. But killing the problem is not really what I wanted. because I want the started application to close properly (maybe saving some configs).

So

Code: Select all

PostMessage_(FindWindow_(@"notepad", 0), #WM_CLOSE, 0, 0)
looks really good. The only problem is that I do not know the name of the window that is created by the started application. So FindWindow_ would not work as the title might differ from the application name. Is searched an appropriate function on MSDN and the WinAPI help, but both are not very helpful i.e. easy to search if you have no idea where to search...

Just for information: I try to write an application launcher for the USB stick. Or better I released the first version already, but this function would be very handy. (See uStart or µStart on the Showcase at purearea.net)
Bye Karl
User avatar
ts-soft
Always Here
Always Here
Posts: 5756
Joined: Thu Jun 24, 2004 2:44 pm
Location: Berlin - Germany

Post by ts-soft »

have a look at the source of pbosl_process lib by Rings.
PureBasic 5.73 | SpiderBasic 2.30 | Windows 10 Pro (x64) | Linux Mint 20.1 (x64)
Old bugs good, new bugs bad! Updates are evil: might fix old bugs and introduce no new ones.
Image
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> sorry, at my first try i forgot or did not use the flag #PB_Program_Open

I see. You made me think I was going insane! ;)
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Klonk
Enthusiast
Enthusiast
Posts: 173
Joined: Tue Jul 13, 2004 2:17 pm

Post by Klonk »

Sorry PBOSL did not give what i searched.

On the german forum I found:

Code: Select all

process = RunProgram(...)
terminateprocess_(process,0) 
which looks very good and seems to do what I want.

I just do not get it working:
example code:

Code: Select all

process = RunProgram("c:\winnt\notepad.exe")
Delay(1000)
TerminateProcess_(process,0)
Can anyone tell me whats wrong here? Or is this the wrong approach??

BTW: I'm trying with PB4b9
Bye Karl
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

This is the only way I know to do it. Not all my own code.

Code: Select all

; RunProgramEx: Retrieves handle of an app's opened window.

Procedure RunProgramEx(filename$,parameter$,directory$,showflag)
  If Left(parameter$,1)<>" " : parameter$=" "+parameter$ : EndIf
  Info.STARTUPINFO : Info\cb=SizeOf(STARTUPINFO) : Info\dwFlags=1
  Info\wShowWindow=showflag : ProcessInfo.PROCESS_INFORMATION
  If CreateProcess_(@filename$,@parameter$,0,0,0,#NORMAL_PRIORITY_CLASS,0,@directory$,@Info,@ProcessInfo)
    ProcessID=ProcessInfo\dwProcessId
    Repeat
      win=FindWindow_(0,0)
      While win<>0
        GetWindowThreadProcessId_(win,@pid.l)
        If pid=ProcessID : WinHandle=win : Break : EndIf
        win=GetWindow_(win,#GW_HWNDNEXT)
      Wend
    Until WinHandle
  EndIf
  ProcedureReturn WinHandle
EndProcedure

app$="c:\windows\notepad.exe" ; Full path needed!
hWnd=RunProgramEx(app$,"",GetPathPart(app$),#SW_SHOW)
Sleep_(2000) ; Give it a couple of seconds to open.
PostMessage_(hWnd,#WM_CLOSE,0,0) ; Now close it.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Klonk
Enthusiast
Enthusiast
Posts: 173
Joined: Tue Jul 13, 2004 2:17 pm

Post by Klonk »

Thank you very much, this is exactly what I searched for.
Could you please tell me the type of the returned result. Is it long?
I want to store the result in a structured list therefore I need the type.

I tried to understand what it does (to improve my knowledge)
1. Parameters for the program are set
2. Create the process
3. Obtain the ProcessID
4. go throught all open windows and check their processIDs
5. When window with same processID is found return handle to that window

Is that correct?
Bye Karl
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

The return type is Long, because PureBasic uses longs by default if the user
doesn't set the type. So because it uses just "WinHandle" instead of another
type like "WinHandle.b" etc, it's a long.

Your steps from 1-5 are correct as to how it works, too. :)

@Fred: Would be great if there was a command to do this after using
RunProgram to launch an app. I experimented a bit but couldn't find
a way?
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Klonk
Enthusiast
Enthusiast
Posts: 173
Joined: Tue Jul 13, 2004 2:17 pm

Post by Klonk »

PB wrote:The return type is Long, because PureBasic uses longs by default if the user
doesn't set the type. So because it uses just "WinHandle" instead of another
type like "WinHandle.b" etc, it's a long.
A very valuable information, didn't found it in the help. Maybe it would make sense to state with Runprogram etc. that the parameter program is of type long?

I took your code and modified it to get a universal code snippet with least use of API functions (works great BTW:):

Code: Select all

;{ ==========================================================================
;|  EndProgram(processID.l)
;|    Closes the application that was started with RunProgram. In difference
;|    to KillProgram it allows the program to shut down properly and save e.g.
;|    settings. The parameter "processID" is obtained by ProgramID(<result of
;|    RunProgram(app$,option$,path$, #PB_Program_Open)>)
;} ==========================================================================
Procedure EndProgram(processID.l)
;***** End a program started with Runprogram, but give chance to save settings!
  If OpenProcess_(#PROCESS_ALL_ACCESS,0,processID)<>0
    CloseHandle_(processHandle)
    Repeat ;searcht through all windows
      win=FindWindow_(0,0)
      While win<>0
        GetWindowThreadProcessId_(win,@pid.l) ; get processID of found window
        If pid=processID : WinHandle=win : Break : EndIf
        win=GetWindow_(win,#GW_HWNDNEXT)
      Wend
    Until WinHandle
    PostMessage_(WinHandle,#WM_CLOSE,0,0) ; Now close the started application 
  EndIf
EndProcedure

 app$="c:\winnt\notepad.exe" ; Full path needed!
 handle.l=RunProgram(app$,"",GetPathPart(app$),#PB_Program_Open)
id.l = ProgramID(handle)
CloeProgram(handle)
 Sleep_(2000) ; Give it a couple of seconds to open.
 EndProgram(id);End started program
With that I a code snippet that I can store for later use.

BTW is there a database for storing those useful codesnippets? I know there is the codearchive which is updated more or less frequently (IMHO less frequently).
Last edited by Klonk on Fri Apr 07, 2006 7:11 pm, edited 2 times in total.
Bye Karl
PB
PureBasic Expert
PureBasic Expert
Posts: 7581
Joined: Fri Apr 25, 2003 5:24 pm

Post by PB »

> A very valuable information, didn't found it in the help

In the v3.94 docs, it's under the "DefType" topic:
http://www.purebasic.com/documentation/ ... ftype.html

In the v4.00 docs, it's under the "Define" topic (because DefType is now Define).

@Fred: Maybe the following text from the topic called "Variables, Types
and Operators" should be changed to the following, because that's where
most people would expect to find an explanation of the default type:

OLD:
To declare a variable in PureBasic, simply type its name. You can also
specify the type you want this variable to be. Variables do not need to be
explicitly declared, as they can be used as "variables on-the-fly". The
Define keyword can be used to declare multiple variables in one statement.


NEW:
To declare a variable in PureBasic, simply type its name. You can also
specify the type you want this variable to be, but if you don't specify a
type then it will be of long (.l) type by default.
Variables do not need to
be explicitly declared, as they can be used as "variables on-the-fly". The
Define keyword can be used to declare multiple variables in one statement.
I compile using 5.31 (x86) on Win 7 Ultimate (64-bit).
"PureBasic won't be object oriented, period" - Fred.
Klonk
Enthusiast
Enthusiast
Posts: 173
Joined: Tue Jul 13, 2004 2:17 pm

Post by Klonk »

Found a problem in my routine, fixed it above. It seems like when additional program are run the handle delivered by RunProgram differs from the new handle. With ProcessID everything works fine.
Bye Karl
Klonk
Enthusiast
Enthusiast
Posts: 173
Joined: Tue Jul 13, 2004 2:17 pm

Post by Klonk »

Anotehr fix for my routine (added above) Added checking whether the process is still running and only then search for the correct window and send message.
Bye Karl
Klonk
Enthusiast
Enthusiast
Posts: 173
Joined: Tue Jul 13, 2004 2:17 pm

Post by Klonk »

I have a program (maybe there are more) that does not react on WM_CLOSE (don't know why). Anything else I could send???

In my Case it was the program SIREN, a renaming tool that did not react.
Bye Karl
Klonk
Enthusiast
Enthusiast
Posts: 173
Joined: Tue Jul 13, 2004 2:17 pm

Post by Klonk »

Just one addition to the code provided by PB:
Add the following into the While loop:

Code: Select all

delay(100)
I found that on certain circumstances (especially when the system is quite busy) the system seems to hang, i.e. opening other applications or windows is extremly slow. This gives the system time to open or launch applications.

In my case this oftenly happend when booting the computer.
Bye Karl
laborde
User
User
Posts: 11
Joined: Fri Feb 17, 2006 1:45 am
Location: Fort Walton Beach, Florida

Missing Commands

Post by laborde »

ts-soft wrote:better close the program after kill

Code: Select all

pid = RunProgram("calc.exe", "", "", #PB_Program_Open)
Delay(1000)
KillProgram(pid)
CloseProgram(pid) ; clear Datas
I have PB Version 3.94 and it does not have the commands "KillProgram()" or "CloseProgram()". How do I add these commands. Also "#PB_Program_Open" cannot be found in the constants list.
Klonk
Enthusiast
Enthusiast
Posts: 173
Joined: Tue Jul 13, 2004 2:17 pm

Post by Klonk »

Well this is a feature of PB4 and works there. As the new version will be officially released soon, please be patient.
Bye Karl
Post Reply