RunProgram()/ShellExecute() child processes

Just starting out? Need help? Post your questions and find answers here.
Straker
Enthusiast
Enthusiast
Posts: 701
Joined: Wed Apr 13, 2005 10:45 pm
Location: Idaho, USA

RunProgram()/ShellExecute() child processes

Post 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.
Image Image
Xombie
Addict
Addict
Posts: 898
Joined: Thu Jul 01, 2004 2:51 am
Location: Tacoma, WA
Contact:

Post 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?
mike74
User
User
Posts: 60
Joined: Mon Nov 21, 2005 1:44 pm

Post by mike74 »

Straker,

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


Mike
Straker
Enthusiast
Enthusiast
Posts: 701
Joined: Wed Apr 13, 2005 10:45 pm
Location: Idaho, USA

Post 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.
Image Image
Straker
Enthusiast
Enthusiast
Posts: 701
Joined: Wed Apr 13, 2005 10:45 pm
Location: Idaho, USA

Post 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.
Image Image
freak
PureBasic Team
PureBasic Team
Posts: 5941
Joined: Fri Apr 25, 2003 5:21 pm
Location: Germany

Post 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.
quidquid Latine dictum sit altum videtur
Straker
Enthusiast
Enthusiast
Posts: 701
Joined: Wed Apr 13, 2005 10:45 pm
Location: Idaho, USA

Post 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
Image Image
Post Reply