B4J Question [JavaPackager] Single Instance

jmon

Well-Known Member
Licensed User
Hello,

I switched to using JavaPackager, but I can't find how to run a single instance of my application. Before I could do it with Launch4J.

Idea anyone?

Regards
Jmon.
 

jmon

Well-Known Member
Licensed User
Thank you.

I made a quick function for anyone that needs it (Depends on Jshell / Windows only):
B4X:
Sub ProcessExists(ExeName As String) As Boolean
    Dim Result As ShellSyncResult
    Dim sh As Shell
    sh.InitializeDoNotHandleQuotes("", "tasklist", Array As String("/FI", $""IMAGENAME eq ${ExeName}""$))
    Result = sh.RunSynchronous(2000)
    Return Not(Result.StdOut.Contains("No tasks are running"))
End Sub
 

jmon

Well-Known Member
Licensed User
Actually for what I needed, this is better:

B4X:
Sub AppStart (Form1 As Form, Args() As String)
    If ProcessCount("myApp\.exe") > 1 Then
        Log("Only one instance of myApp allowed.")
        ExitApplication(2)
    End If
End Sub

Sub ProcessCount(ExeNamePattern As String) As Int
    Dim Count As Int = 0
    Dim Result As ShellSyncResult
    Dim sh As Shell
    sh.InitializeDoNotHandleQuotes("", "tasklist", Null)
    Result = sh.RunSynchronous(2000)
    If Result.Success = False Then Return Count
    Dim Match As Matcher  = Regex.Matcher2(ExeNamePattern, Regex.CASE_INSENSITIVE, Result.StdOut)
    Do While Match.Find
        Count = Count + 1
    Loop
    Return Count
End Sub
This code checks if one instance of the app is running, if it is, the close the app. Note that the Process name has to be written as a regex, so you have to escape the dot (\.).
 

tdocs2

Well-Known Member
Licensed User
Good Work ^2, jmon!

Your generosity is to be commended.

Thank you.

Sandy
 

tdocs2

Well-Known Member
Licensed User
Hello, jmon.

I tried your sub in post #3, but I must be doing something wrong... Your sub returns True whether notepad.exe is running or not.

My Code is included. Also, log is shown.

Your help is appreciated.

Thank you.

Sandy

B4X:
Sub BShell_MouseClicked (EventData As MouseEvent)
    Dim shellexe As String
    shellexe="c:\Windows\System32\notepad.exe"
    Dim exerunning As Boolean
    exerunning=ProcessExists(shellexe)
    Log ("exerunning "&exerunning)
End Sub

Sub ProcessExists(ExeName As String) As Boolean
    Dim Result As ShellSyncResult
    Dim Sh As Shell
    Sh.InitializeDoNotHandleQuotes("", "tasklist", Array As String("/FI", $""IMAGENAME eq ${ExeName}""$))
    Result = Sh.RunSynchronous(2000)
    Log("Result.StdOut = " & Result.StdOut)
    Return Not(Result.StdOut.Contains("No tasks are running"))
End Sub
Log:
B4X:
Program started.
Result.StdOut =
exerunning true
 

Erel

Administrator
Staff member
Licensed User
Simpler approach:
B4X:
Sub MainForm_MouseClicked (EventData As MouseEvent)
  Dim shellexe As String
  shellexe="notepad.exe"
  Dim exerunning As Boolean =ProcessExists(shellexe)
  Log ("exerunning "&exerunning)
End Sub

Sub ProcessExists(ExeName As String) As Boolean
  Dim Result As ShellSyncResult
  Dim Sh As Shell
  Sh.InitializeDoNotHandleQuotes("", "tasklist", Null)
  Result = Sh.RunSynchronous(5000)
     Return Result.StdOut.ToLowerCase.Contains(ExeName.ToLowerCase)
End Sub
 

tdocs2

Well-Known Member
Licensed User
Thank you, Erel.

It works as advertised.

Now, if notepad is not running I start Notepad via shell (see modifications below).

If it is running, how do I give it focus?

Sandy

B4X:
Sub BShell_MouseClicked (EventData As MouseEvent)
  Dim shellexe As String
  shellexe="notepad.exe"
  Dim exerunning As Boolean =ProcessExists(shellexe)
  Log ("exerunning "&exerunning)
  If exerunning = False Then
      shell1.initialize("shell1","c:\Windows\System32\notepad.exe",list1)
      shell1.Run(-1)
  End If
End Sub

Sub ProcessExists(ExeName As String) As Boolean
  Dim Result As ShellSyncResult
  Dim Sh As Shell
  Sh.InitializeDoNotHandleQuotes("", "tasklist", Null)
  Result = Sh.RunSynchronous(5000)
     Return Result.StdOut.ToLowerCase.Contains(ExeName.ToLowerCase)
End Sub
 
Top