Execfile

Blitz3D Forums/Blitz3D Programming/Execfile

solitaire(Posted 2005) [#1]
Is it possible to close a window(process)
that i startet with
Execfile?

Thanks,
soli


WolRon(Posted 2005) [#2]
AFAIK, only if you wrote it yourself to be able to do so.
Although using the Windows API, you may be able to?

Don't know if this is any help:
Example

As a practical example, consider how to shut down V++ from a module (there's no built-in function to do this). You can shut down by using SendMessage to send the main V++ window a Windows wm_Close message.

In order to send the message, you first need to declare another API function, FindWindow, which you use to determine the handle of the main V++ window.

The technique is illustrated in the sample module Close.v which you can download.

found on http://www.digitaloptics.net/technical/vpascal/winapi.htm


John Blackledge(Posted 2005) [#3]
Yes, Execfile's no good for this.

You must use an API lib to run the program, Find the hWnd, then use SendMessage(hWnd, WM_CLOSE,0,0).


jfk EO-11110(Posted 2005) [#4]
If you mean end a program by "close a window" then John is right. If it's only a DOS-Box that remains on screen when the Programm ended then you may call the Dos Program with the "/c" flag to make sure it will close after execution, eg:
ExecFile "command /c ping.exe 127.0.0.1 >testping.txt"



solitaire(Posted 2005) [#5]
Sorry, i didn't get it to work

All i want to do is starting a helpfile,
and prevent the user from opening dozens of times.

;own window for testing
Graphics 600,400,16,2
AppTitle "mywindow"


Global handlewinhlp%

;the app that i wanted to execute
If FileType("c:/windows/winhlp32.exe")=1 Then helpprogramm$="winhlp32"
If FileType("c:/windows/winhlp.exe")=1 Then helpprogramm$="winhlp"
	
;my rules-file
mydir$="d:/eigene dateien/blitz/games/as-solitaire/"
helpfile$=mydir$+"soli.hlp"

;only importand for my-file
tmpas=23 ; pointer for testing
parameter$=" -I SHM_contents"
number$=Right$("0000"+Str$(tmpas),4)

;here i start the app
ExecFile (helpprogramm$+" "+parameter$+number$+" "+helpfile$)		

;only for testing, i wait until the app has startet properly
Delay 1000		

;i get a handle, everything is fine.				
handlewinhlp%=api_FindWindow(0,"AS-Solitaire Spielregeln") 			
DebugLog handlewinhlp%

;i wait until i want to close the help-window
WaitKey()

; i get an "Memory Access Violation" :-((((
api_SendMessage(handlewinhlp%,WM_CLOSE,0,0)
	
	
; wait to end 
While Not KeyHit(1)
Wend
End


Maybe i need OpenProcess or CreateProcess,
but i don't know enought about WinApi to do so.
Is there anybody who could help me, please?
soli


Baystep Productions(Posted 2005) [#6]
Check the kernel userlibs or other windows system dlls


Picklesworth(Posted 2005) [#7]
OpenProcess would work, if you know how to create the crazy thing that you need to pass to it :S
I don't.

It does return a handle to the process though, so ending it would be easy.


John Blackledge(Posted 2005) [#8]
Looking through my old Windows 'C' I see the method I have used in the past is:
int PASCAL WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
 if(!hPrevInstance)
  { // create the window
  }

In other words when a window is created Windows sends a value hPrevInstance which indicates a previous instance, and then the logic below prevents opening another one of the same.

Not trying to be baffling here, but this is how it is done in strict 'C'.

I think helpfiles are another thing altogether though, and I think you would have to communicate/interact with WIndows Help runner to achieve this, though I'm afraid I haven't done any work along these lines since Blitz came along so my knowledge is probably hopelessly out of date.

I'd suggest you go to the Microsoft Knowledge Base website, no matter which language you are trying to code this in.


VIP3R(Posted 2005) [#9]

All i want to do is starting a helpfile, and prevent the user from opening dozens of times.


Check soja's post in the following thread for a method of doing that. It uses the 'CreateMutexA' function from the kernel32.dll WinAPI, so you need to create a userlib decls file (included in the post). The code works fine in BlitzPlus, but it should work ok with Blitz3D too (remember to remove the 'Notify' function references).

http://www.blitzmax.com/Community/posts.php?topic=28740

"My Program Instance" is the name of the program (in the title bar) which you want to detect.

Use it to detect whether the program is already open, then you can decide whether to call ExecFile or not based on the result.


John Blackledge(Posted 2005) [#10]
Sadly the method described in the thread does not work:
CreateMutex(0,1,"My Help File")
If GetLastError() = ERROR_ALREADY_EXISTS Then
 result = 0
Else
 result = 1
EndIf
If result = 1
 ExecFile("help\help.chm")
EndIf

result = 1 is always the case, so Execfile is always called.

Can anyone else clarify this?


VIP3R(Posted 2005) [#11]
Just tried it and it does work ok, but it only seems to work when another instance of the Blitz3D program is running.

Try this code and run it twice, the first will display 'Nope' and the second will display 'Yep'.

Graphics 640,480,0,2

AppTitle "hello"

Const ERROR_ALREADY_EXISTS=183

CreateMutex(0,1,"hello")

If GetLastError()=ERROR_ALREADY_EXISTS
	Text 0,0,"Yep"
	Else
	Text 0,0,"Nope"
	End If

WaitKey()

But when I tried to detect notepad for example, it didn't seem to detect it was running for some reason :/

[edit] It appears the program title in CreateMutex(0,1,"ProgramTitle") doesn't work in Blitz3D like it does in BlitzPlus, but it still detects another Blitz3D program running regardless of the program title used. In this case it won't be of any use unfortunately. It would only be useful for detecting whether any other Blitz3D program is running.


John Blackledge(Posted 2005) [#12]
The point is that solitaire (and I) are trying to run a helpfile once only from our app, not run our app only once.

Any futher ideas?


VIP3R(Posted 2005) [#13]
Yes I know, the idea was to detect CreateMutex(0,1,"WhateverYourHelpFileIsCalled") and use ExecFile accordingly.

I'm guessing it must be possible with some other Win API functions, but I've no idea which ones.


Picklesworth(Posted 2005) [#14]
If you give up, you could use one of Windows' built in help file apps, which probably prevents repeated opening automatically.


solitaire(Posted 2005) [#15]
@John Blackledge

Not exactly, to run the app only once could be done like this.

Graphics 600,400,16,2
AppTitle "mywindow"

Global handlewinhlp%
Global apptitlename$="Rechner"
Global appname$="c:/windows/calc.exe"

	
; to show that it only run once
While Not KeyHit(1)

	handlewinhlp%=api_FindWindow(0,apptitlename$) 
			
	If handlewinhlp%=0
		ExecFile (appname$)
		
		;wait until the app is open
		Delay 1000

	EndIf

Wend
End


But what i need, for example is.
open Rules-Klondike and then open
Rules-Freecell in the same window,
or close the first window, and open
a new one.


John Blackledge(Posted 2005) [#16]
Ok I modified your code for English, then ran it...
Graphics 600,400,16,2
AppTitle "mywindow"
Global handlewinhlp%
Global apptitlename$="Calculator"
Global appname$="calc.exe"
; to show that it only run once
While Not KeyHit(1)
	handlewinhlp%=api_FindWindow(0,apptitlename$) 
	If handlewinhlp%=0
		ExecFile (appname$)
		;wait until the app is open
		Delay 1000
	EndIf
Wend
End

and get

So what was your point again?


solitaire(Posted 2005) [#17]
The user32.decls must look like this:

.lib "user32.dll"
api_FindWindow% (lpClassName%, lpWindowName$) : "FindWindowA"

The "%" in lpClassName% is the important thing.


John Blackledge(Posted 2005) [#18]
Can I just take a moment to go AARRGGHH!

Yes, you're right. It was down to the definition.
My old def was
api_FindWindow%(lpClassName$,lpWindowName$):"FindWindowA"

Yours works perfectly and _finally_ I have the control I need over runniing a help file. Many thanks!

Now, how many other definitions do I have which are wrong, but which I thought simply didn't work?