Page 1 of 1

RunProgram()/ShellExecute() child processes

Posted: Thu Jul 20, 2006 11:24 pm
by Straker
I have a question regarding RunProgram() and/or ShellExecute() with regard to the programs that they launch.

If Program A calls RunProgram/ShellExecute to launch Program B, does Program B become a child process of Program A? Even if Program A exits after launching Program B?

Here is my specific dilemma: I have an application that when it starts checks for an update for the application. If there is a new version it exits, but not before it launches the updater application - which begins the update, however the main exe file is not overridden, except when the updater application is run by itself, not by the parent app. Its pretty frustrating...

Maybe... is there a way to make an application run as its own independent process and not a child?

Thanks.

Posted: Fri Jul 21, 2006 10:37 pm
by Xombie
Howdy Straker,

Have you thought about taking a different direction? What about making the main executable a front-end for your program? It launches, checks the current version of the .exe (which could be named whatever you like - including an odd extension) and then checks the latest version wherever it is. If everything is the same, great, call ShellExecute_() or CreateProcess_() to run the main program (which could even be called straker.bob). If versions are different, it copies over whatever files need to be updated and then launches the new program.

You could even make the loader program display a little flash screen with info about what's going on (Loading 'Blah.blh', etc...).

Otherwise, I'll dig. From what I recall, it should be no problem overwriting a file as long as it's not running and not named the same. I'll create a little test to see what's what, though.

-Update-

Try these out...

Code: Select all

; This is the original program that will hopefully get overwritten.
Define.l a, b, c, e
Define.s d
a = 1
b = 0
c = 25
d = "Update02.exe"
MessageRequester("Version Info", "Hello.  I am version "+Str(a)+"."+Str(b)+"."+Str(c))
If a = 1
   ;
   e = ShellExecute_(#Null, @"open", @"Update02.exe", #Null, #Null, #SW_HIDE)
   ;
   If e = 0 : MessageRequester("", "Error Creating Process") : EndIf
   ;
EndIf
;-
End
;-
Saved as 'Update01.pb' and compiled as 'Update01.exe'

Code: Select all

; This is the updating program.
Define.l a
Define.s b
DeleteFile("Update01.exe")
CopyFile("Update03.exe", "Update01.exe")
b = "Update01.exe"
a = ShellExecute_(#Null, @"open", @"Update03.exe", #Null, #Null, #SW_HIDE)
If a = 0 : MessageRequester("", "Error Creating Process") : EndIf
End
Saved as 'Update02.pb' and compiled as 'Update02.exe'

Code: Select all

; This is the version that will overwrite the 'old' version.
Define.l a, b, c, e
a = 2
b = 0
c = 0
MessageRequester("Version Info", "Hello.  I am version "+Str(a)+"."+Str(b)+"."+Str(c))
End
Saved as 'Update03.pb' and compiled as 'Update03.exe'

Compile those three and run 'Update01.exe' and see if it works. Is that what you were looking for?

Posted: Sat Jul 22, 2006 12:29 am
by mike74
Straker,

You can use RunProgram to launch a .bat file that starts the updater if this is in Windows.


Mike

Posted: Sat Jul 22, 2006 3:22 am
by Straker
Thanks for the replies. I am on my way out the door for 5 days, so I won't be able to test them out, but I will when I get back! I will post my results here.

Thanks again.

Posted: Sat Jul 29, 2006 4:21 am
by Straker
Hi Xombie.

Yes, your examples illustrate my point exactly. Update03.exe is NOT overwriting Update01.exe when Update02.exe is called.

Update02.exe only works (overwrites 01 with 03) when I call it by itself, not when its called from Update01.exe

Update01.exe runs the same no matter how many times I run it. Only when I call Update02.exe does it change.

I have updated the Update02.pb code here to give a message when the copy fails:

Code: Select all

; This is the updating program.
Define.l a,c
Define.s b
DeleteFile("Update01.exe")

c = CopyFile("Update03.exe", "Update01.exe")
If c = 0 : MessageRequester("", "Error Copying Files") : EndIf

b = "Update01.exe"
a = ShellExecute_(#Null, @"open", @"Update03.exe", #Null, #Null, #SW_HIDE)
If a = 0 : MessageRequester("", "Error Creating Process") : EndIf

End
I guess this is why in my original post, I was hoping for a "DetachMeFromMyParentProcessThread" API call or something of the sort, to allow Update02.exe to really overwrite Update01.exe which is its parent process.

Cheers.

Posted: Sat Jul 29, 2006 8:28 pm
by freak
It does not work because the parent is still running while you try to replace it. (which causes the file to be locked)
You can simply check the result of DeleteFile() and try it in a loop until it succeeds. (it should succeed as soon as the parent quits).
Of course there should be a timeout in case the program is on readonly media.

Posted: Sun Jul 30, 2006 12:05 am
by Straker
Thanks freak. That is what I assumed. I wrote Kill-N-Launch to handle this issue. Now in the annoucements forum:

http://www.purebasic.fr/english/viewtopic.php?p=154986