B4J Code Snippet [B4J] Restart App

hello everyone,
Here is a slightly improved code that allows you to restart the application at any time:

code source by @byz:

Main Form::
#Region Project Attributes
    #MainFormWidth:  600
    #MainFormHeight: 880
    #PackagerProperty: ExeName = Your.exe
'    #IgnoreWarnings:
#End Region

B4XMainPage::
Private Sub Button1_Click
    RestartSelf("Your.exe")
End Sub

Private Sub RestartSelf(exeName As String)
    Try
'       shl.Initialize("shl", "java.exe", Array As String("-jar", exeName))  'Your.jar
        shl.Initialize("shl", "cmd.exe", Array As String("/c", exeName))     'Your.exe
        shl.WorkingDirectory = File.DirApp
        shl.Run(-1)
    Catch
        Log(LastException.Message)
    End Try
    Sleep(0)
    ExitApplication
End Sub
 
Last edited:

aeric

Expert
Licensed User
Longtime User
Hi @T201016,
May I know this snippet is improved from which code?

I also have seen a similar post here:
 

T201016

Active Member
Licensed User
Longtime User
Hello,
Yes, it's the same code that I slightly modified (see line 8 in B4XMainPage). Example @byz as it stands didn't work for me.
In the example, I provide the application name without the full path, but I set the application directory (i.e. shl.WorkingDirectory = File.DirApp)
 
Last edited:

aeric

Expert
Licensed User
Longtime User
Hello,
Yes, it's the same code that I slightly modified (see line 8 in B4XMainPage). Example @byz as it stands didn't work for me.
I see.
I tested byz's code. It worked for me most of the time but does fail sometimes.
I haven't tested your code.

I think you missed the declaration for the shell.
B4X:
Private shl As Shell
 

T201016

Active Member
Licensed User
Longtime User
I think you missed the declaration for the shell.
No, I have it declared globally in the project. As for it not working sometimes, it's a shell issue
PS. I checked my modified example and it works for both .exe and .jar
 
Last edited:

Magma

Expert
Licensed User
Longtime User
I think that.. to be sure for working....
Need to have a time sleep ~10sec .. that no db or file will be opened...when app starts...

All have to do how fast disks have.. how will work exitapplication too.. if opened db, or files... need fast close them.
 

aeric

Expert
Licensed User
Longtime User
In my case, this code snippet doesn't work for me while byz's code works for me.
I think this is because the shell which will be executed from the "running process" exe is inside \bin directory must call the "start-up" exe which is located 1 level up from the \bin directory as you can see in run_debug.bat
 

T201016

Active Member
Licensed User
Longtime User

Can you tell me how you initialize the shell?

My example is based solely on the executable file (.jar / .exe) - I think that in order to call from the .bat batch file you need to initialize the shell differently.
 

T201016

Active Member
Licensed User
Longtime User
I understand that you have correctly specified the working directory, as you suggested ("\bin")
 

T201016

Active Member
Licensed User
Longtime User
Very interesting,, several versions of the code and different operation I have to check this change for myself. The important thing is that it works.
 

T201016

Active Member
Licensed User
Longtime User
I changed to following:
B4X:
shl.WorkingDirectory = File.GetFileParent(File.DirApp)
Now, it works.
I performed the test again and launched the application placed in the D:\TMP directory from where its .exe file was launched
I received:

shl.WorkingDirectory = File.GetFileParent(File.DirApp)
Log(shl.WorkingDirectory) '--------------------------- >> D:\
shl.WorkingDirectory = File.DirApp
Log(shl.WorkingDirectory) '--------------------------- >> D:\TMP
The refore, the 'File.GetFileParent' function returns the path of the parent (i.e. always root) file or folder, as instructed.
So, in my humble opinion, the function: 'File.GetFileParent(File.DirApp)' should not work, contrary to nature,
so why does it work for you? I have no idea.

PS. The function is usually used to return the full path and extract the file name itself from this path..., i.e.: File.GetFileParent and File.GetName
 
Last edited:

aeric

Expert
Licensed User
Longtime User
I am not sure how you produce the exe. Are you using Launch4j to create a single exe?

I create my exe using "Build Standalone Package" from B4J IDE menu where I get:
1 App.exe file in my ProjectName\B4J\Objects\temp\build ~17KB
1 App.exe file in my ProjectName\B4J\Objects\temp\build\bin ~46KB

When I run the 17KB App.exe, I think it is actually calling the 46KB App.exe inside \bin folder
and the 46KB App.exe is actually a copy of java.exe (~46KB) that being renamed.
What is showing on the Windows taskbar during runtime is the 46KB App.exe.

The 17KB App.exe behaves like a bootstrap or just a shortcut which will execute the following commands:
\bin\App.exe @release_java_modules.txt -m b4j/your.package.name.main

So I need to either restart the
App.exe (17KB) inside \build folder
or
App.exe (46KB) inside the \build\bin folder with extra parameters.

Either one of the following works for me:
B4X:
shl.Initialize("shl", "cmd.exe", Array As String("/c", "App.exe"))
shl.WorkingDirectory = File.GetFileParent(File.DirApp)
B4X:
shl.Initialize("shl", "App.exe", Array As String("@release_java_modules.txt", "-m", "b4j/your.package.name.main"))
shl.WorkingDirectory = File.DirApp
 

Magma

Expert
Licensed User
Longtime User

Hmm... the second i think is wrong... there is no meaning running app.exe with parameters of java runtime... may be working because just runs the exe...

If need to run javac.exe java.exe with jar...
need
B4X:
shl.Initialize("shl", "java.exe", Array As String("@release_java_modules.txt", "-m", ____________here____may be have other parameters too__________, "b4j/your.package.name.main"))

or you can run batch file that needs, the path of batch and cmd.exe with parameters "/c" and "batchfilenamewithext"
 
Last edited:

Magma

Expert
Licensed User
Longtime User
But...

I was thinking the other what is the meaning of running "yourself exe"...

A scenario is when updating... but update is not secure if not replace the whole bin folder!
For me is better using an extra app (standalone) as a middleware that will the same work everytime...
In this scenario you must have all data (except of the exe) of your app in "DirData" and not in "DirApp"

for example:
C:\appfolder\yourapp
C:\appfolder\updater

When is time for update:
1. shell the updater, wait some seconds and exitapplication
2. The updater will download the new zip (having the whole bin folder)
3. When downloaded, will "kill" the "yourapp" (because sometimes the exitapplication not working... perhaps of locked db/files and etc)
4. Delete the bin folder
5. Extract the new downloaded binfolder.zip as bin folder
7. Shell the "yourapp" - wait some secs, and exitapplication
8. Yourapp... at startup after some secs will kill "updater" - to be sure not running any more

This is ofcourse a scenario... and not for all cases...
 

aeric

Expert
Licensed User
Longtime User
Hmm... the second i think is wrong... there is no meaning running app.exe with parameters of java runtime... may be working because just runs the exe...
Please don't assume. Do a test. You will understand.
 

aeric

Expert
Licensed User
Longtime User
shl.WorkingDirectory = [pathofjava_you can get it from %PATH% using some system events code]
I think you have confused the java.exe in the standalone package and the java.exe in the JDK.
 
Cookies are required to use this site. You must accept them to continue using the site. Learn more…