B4J Question How to set process name with B4JPackager11? [SOLVED]

Discussion in 'B4J Questions' started by jmon, Aug 16, 2019.

  1. jmon

    jmon Well-Known Member Licensed User

    Hello,

    With the previous version of B4JPackager (Java8), the process name had the same name as the executable (i.e. my executable was named MyGame.exe, the process in Windows process manager was named MyGame.exe).

    With B4JPackager11, the process is named javaw.exe, regardless of my executable name. Is there a way to change the name of the process?

    Thank you for the support!

    Edit: for info, the problem that this causes, is that I cannot use this function anymore:
    https://www.b4x.com/android/forum/threads/singleton-and-process-functions.61381/#content
    And setting the searched process name to javaw.exe would be too broad I guess

    Edit: Solved HERE
     
    Last edited: Aug 19, 2019
  2. jmon

    jmon Well-Known Member Licensed User

    At the moment, I haven't found how to change the application process name, but I found a solution that fits my needs (Singleton) and works with B4JPackager11:

    EDIT2: See the next solution POST #3 for a correct answer (This one always return false since it counts this process as existing)
    Code:
    Sub AppStart (Form1 As Form, Args() As String)
        MainForm = Form1
        
    'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
        MainForm.Show
     
        
    Wait For(SingleInstance("")) Complete (Singleton As Boolean)
        
    Log($"Is my app already running: "$ & Singleton)
     
    End Sub

    'Returns true if the provided package name is not found.
    'PackageName: If empty, the function with use the current package name.
    Sub SingleInstance(PackageName As StringAs ResumableSub
        
    If PackageName = "" Then
            
    Dim joPKG As JavaObject
            joPKG.InitializeStatic(
    "anywheresoftware.b4a.BA")
            PackageName = joPKG.GetField(
    "packageName")
        
    End If
        
    Dim wmic As Shell
        wmic.InitializeDoNotHandleQuotes(
    "wmic""wmic.exe"Array As String("PROCESS"))
        wmic.Run(
    20000)
        
    Wait For wmic_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
        
    If Success Then
            
    Return Not(StdOut.ToLowerCase.Contains(PackageName.ToLowerCase))
        
    Else
            
    Return True
        
    End If
    End Sub
    That works because with B4JPackager11 the app appears to be ran via command line and appear like this in wmic.exe:
    You can leave the package name empty if you want, the function will determine this app package name automatically, or you can pass another package name.

    EDIT: Note that this will ONLY work when the application is compiled with B4JPackager, it will not work in the IDE!
     
    Last edited: Aug 17, 2019
  3. jmon

    jmon Well-Known Member Licensed User

    Update:
    This is better for what I need, this function counts the number of app with my package name running and close if there is more than 1:
    Code:
    Sub AppStart (Form1 As Form, Args() As String)
        MainForm = Form1
        
    'MainForm.RootPane.LoadLayout("Layout1") 'Load the layout file.
        MainForm.Show

        
    Wait For(PackageCount("")) Complete (Count As Int)
        
    Log($"Count of my app running: "$ & Count)
        
    If Count > 1 then ExitApplication
       
    End Sub

    'Returns the number of packages found.
    'PackageName: If empty, the function with use the current package name.
    Sub PackageCount(PackageName As StringAs ResumableSub
        
    Dim Count As Int = 0
        
    If PackageName = "" Then
            
    Dim joPKG As JavaObject
            joPKG.InitializeStatic(
    "anywheresoftware.b4a.BA")
            PackageName = joPKG.GetField(
    "packageName")
        
    End If
        
    Dim wmic As Shell
        wmic.InitializeDoNotHandleQuotes(
    "wmic""wmic.exe"Array As String("PROCESS"))
        wmic.Run(
    20000)
        
    Wait For wmic_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
        
    If Success Then
            
    Dim Match As Matcher  = Regex.Matcher2(PackageName, Regex.CASE_INSENSITIVE, StdOut)
            
    Do While Match.Find
                Count = Count + 
    1
            
    Loop
            
    Return Count
        
    Else
            
    Return 0
        
    End If   
    End Sub
     
  4. Erel

    Erel Administrator Staff Member Licensed User

    It shouldn't be too difficult to change the process name. Change the value of FileName in BuildRunner sub and then change the name of javaw.exe under the bin folder.
     
    Chris2 and jmon like this.
  5. jmon

    jmon Well-Known Member Licensed User

    Yeah, good idea!
     
  6. jmon

    jmon Well-Known Member Licensed User

    That works very well, and it was easy to do. This is the updated BuildRunner to make the application process name correct in windows:
    Code:
    Private Sub BuildRunner As ResumableSub
        
    If Windows Then  
            
    Dim FileName As String = ExeName
            
    Dim target As String = "winexe"
            
    Dim output As String = ExeName
            
    File.WriteString(TempFolder, "runner.cs"$"
       
    using System;
    using System.Diagnostics;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.IO;
    namespace B4JRunner
    {
        class Program
        {
            static void Main(string[] args)
            {
                Process p = new Process();
                p.StartInfo.FileName = "$
    {FileName}";
                p.StartInfo.WorkingDirectory = Path.Combine(System.AppDomain.CurrentDomain.BaseDirectory, "bin");
                p.StartInfo.Arguments = "@release_java_modules.txt -m ${
    TargetModule}/${PackageName}.main";
                foreach (string a in args)
                    p.StartInfo.Arguments += " " + "\"" + Regex.Replace(a, @"(\\+)$", @"$
    {"$1$1"}") + "\"";
                p.Start();
            }
        }
    }"$
    )
            
    If IconFile = "" Then
                
    File.Copy(File.DirAssets, "icon.ico", TempFolder, "icon.ico")
            
    Else
                
    File.Copy(IconFile, "", TempFolder, "icon.ico")
            
    End If
            
    Wait For (RunShell(True, NetFrameworkCSC , Array($"/target:${target}"$"/win32icon:icon.ico"$"/out:build\${output}"$"runner.cs"))) complete (output As String)
            
    File.WriteString(TempFolder, "build\run_debug.bat"$"
        cd bin
    java.exe @release_java_modules.txt -m ${
    TargetModule}/${PackageName}.main
    pause
    "$
    )
            
    File.Copy(File.Combine(TempFolder, "build/bin"), "javaw.exe"File.Combine(TempFolder, "build/bin"), ExeName)

        
    Else
            
    File.WriteString(TempFolder, "build/run.command"$"#!/bin/bash
    cd -- "$
    {"$"}(dirname -- "${"$"}BASH_SOURCE")"
    cd bin
    ./java @release_java_modules.txt -m ${
    TargetModule}/${PackageName}.main
    exit 0
     "$
    )
            
    Dim jo As JavaObject
            jo.InitializeNewInstance(
    "java.io.File"Array As String(File.Combine(TempFolder, "build/run.command")))
            jo.RunMethod(
    "setExecutable"Array As Object(TrueFalse))      
        
    End If
        
    Return True
    End Sub
    (Note: I didn't rename javaw.exe to the Exename, I just copied it. I figured one could need javaw.exe for other purposes.)
    That could be a permanent addition to B4JPackager11.
     
    Chris2, inakigarm and DonManfred like this.
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice