Launching an application from a Web App

I’m writing a load balancer which is itself a web application. I want to be able to restart an instance of another web app when certain criteria are met.

However, I’m struggling. If I start an instance of a web app using a Shell, the Shell object remains the whole time the web app is running. I don’t want this, I just want the shell to launch the app and then be destroyed (go out of scope).

I also can’t use FolderItem.Launch as my balancer is a webapp and so FolderItem.Launch is not available.

How can I get my webapp to simply launch another application?

Thanks in advance.

What platform are you hosting on?

This is what I wrote to launch an app that is independent of the app that launched it. I assume it will run from a web app, as I run it from a console app:

[code]Protected Sub doRunBackgroundAppWAD(f As FolderItem, scriptDelay As Double = 0)
'allows you to launch a second application (e.g. Console app) then quit the first app without that then taking down the second app
'forum.xojo.com/20031-console-app-updater
'forum.xojo.com/7379-console-app-basics-quitting-possible
'forum.xojo.com/18064-making-a-shell-script-survive-quit
'forum.xojo.com/15981-shell-w-external-applications
Dim tempShell As New Shell
Dim tempString As String

if f = nil or not f.Exists then Return

#if TargetWin32 then
'tempString = "start " + chr(34) + chr(34) + " " chr(34) + f.Parent.NativePath + if(right(f.Parent.NativePath, 1) = “”, “”, “”) + chr(34) + f.Name + chr(34) 'this works too!
tempString = "start " + chr(34) + chr(34) + " " + chr(34) + f.NativePath + chr(34) 'start “” “c:\path with spaces\app.exe” param1 “param with spaces”

#elseif TargetLinux then
tempShell.Execute("chmod +x " + f.ShellPath) 'Linux needs the executable bit turned on!
tempString = “nohup " + f.ShellPath + " &” 'No Hang Up. Stops the child shell being killed once the parent shell is quit

#elseif TargetMacOS then
tempShell.Execute(“chmod +x " + f.ShellPath) 'not sure if MacOS X needs the executable bit turned on after unzipping?
'tempString = “nohup " + f.ShellPath + " &” 'No Hang Up
'tempString = f.ShellPath + " &”
tempString = “open -a " + f.ShellPath + “; exit” + f.ShellPath + " &” '-a for application 'open -a Mail; exit

#endif
tempShell.Mode = 1 '0 Synchronous 1 Asynchronous
tempShell.TimeOut = 10000 'milliseconds
tempShell.Execute(tempString)
DelayMBS scriptDelay 'give the script time enough to launch the app
tempShell.Close

Exception err
commonOS.doHandleExceptionWAD(err, CurrentMethodName)

End Sub
[/code]

@Wayne Golding I’m running on Windows.
@David Cox Thanks, I’ll give your settings a go!

On Windows create a service for each instance and use the service control manager to start & stop as required. While this does require the use of a shell, the instance is short lived.

@David Cox I tried your settings but the Shell remains running as before.

@Wayne Golding Thanks for the suggestion but that’s quite a change to our support methodology. I just want to start an app and be done with it!

A question for the Xojo guys is, why is FolderItem.Launch not available from a WebApp?

Windows Functionality Suite has this method that works in a Web application:

Function LaunchAndNotWait(extends f as FolderItem, params as String = "", deskName as String = "") As Uint32
		  // We want to launch the application and not wait for
		  // it to finish executing before we return.
		  dim rc As Uint32
		  
		  #if TargetWin32
		    
		    Soft Declare Function CreateProcessW Lib "Kernel32" ( appName as WString, params as WString, _
		    procAttribs as Integer, threadAttribs as Integer, inheritHandles as Boolean, flags as Integer, _
		    env as Integer, curDir as Integer, startupInfo as Ptr, procInfo as Ptr ) as Boolean
		    
		    Soft Declare Function CreateProcessA Lib "Kernel32" ( appName as CString, params as CString, _
		    procAttribs as Integer, threadAttribs as Integer, inheritHandles as Boolean, flags as Integer, _
		    env as Integer, curDir as Integer, startupInfo as Ptr, procInfo as Ptr ) as Boolean
		    
		    Soft Declare Function CloseHandle Lib "Kernel32" ( handle as Integer ) As Boolean
		    
		    Soft Declare Function GetLastError Lib "Kernel32" ( ) As Uint32
		    
		    dim startupInfo, procInfo as MemoryBlock
		    
		    startupInfo = new MemoryBlock( 17 * 4 )
		    procInfo = new MemoryBlock( 16 )
		    
		    dim unicodeSavvy as Boolean = System.IsFunctionAvailable( "CreateProcessW", "Kernel32" )
		    
		    startupInfo.Long( 0 ) = startupInfo.Size
		    
		    dim deskStr as MemoryBlock
		    if deskName <> "" then
		      if unicodeSavvy then
		        deskStr = ConvertEncoding( deskName + Chr( 0 ), Encodings.UTF16 )
		      else
		        deskStr = deskName + Chr( 0 )
		      end if
		      
		      startupInfo.Ptr( 8 ) = deskStr
		    end if
		    
		    dim ret as Boolean
		    if unicodeSavvy then
		      ret = CreateProcessW( f.AbsolutePath, params, 0, 0, false, &h10, 0, 0, startupInfo, procInfo )
		    else
		      ret = CreateProcessA( f.AbsolutePath, params, 0, 0, false, &h10, 0, 0, startupInfo, procInfo )
		    end if
		    
		    if ret then
		      
		      call CloseHandle( procInfo.Long( 0 ) )
		      call CloseHandle( procInfo.Long( 4 ) )
		      
		    else
		      
		      rc = GetLastError()
		      
		    end if
		    
		  #else
		    
		    #pragma unused f
		    #pragma unused params
		    #pragma unused deskName
		    
		  #endif
		  
		  Return rc
		  
End Function

Are you starting the shell from a Session or from App?