B4J Library jShell library

tuicemen

Member
Licensed User
I've tried to use taskkill unsuccessfully with this library
Taskkill works fine in windows command prompt (taskkill /IM PcCompanion.exe /t /f) however I seem to be missing something in my code:confused::
SHL.Initialize("shl","\TaskKill" , ArrayAsString(" /IM PcCompanion.exe /t /f"))
SHL.WorkingDirectory = ("\")
SHL.Run(-1)

I'm also not clear as to how to get the StdOut and StdErr strings which may help me figure this out:confused:
 

Alberto Iglesias

Well-Known Member
Licensed User
If I want to run B4iBuildServer.jar from jSHELL, how we can to this?

I try:

B4X:
Dim shl AsShell
shl.Initialize("shl", "java", ArrayAsString("-jar", "B4iBuildServer.jar"))
shl.WorkingDirectory = "/Users/myuser/Development/B4i-MacServer"
but not working....

Have any idea?
 

Erel

Administrator
Staff member
Licensed User
What are the values of StdErr and StdOut in ProcessCompleted?
 

koaunglay

Member
Licensed User
The jShell library allows you to start other programs. It is based on Apache Commons Exec project: http://commons.apache.org/proper/commons-exec/index.html

The programs are always started asynchronously. ProcessComplete event is raised when the process completes.

The following code will run the Java program we previously created:

B4X:
Sub AppStart (Args() As String)
   Dim shl As Shell
   shl.Initialize("shl", "java", _
     Array As String("-cp", "curl.jar", "b4j.example.main", "http://www.basic4ppc.com"))
   shl.WorkingDirectory = "C:\Users\H\Documents\B4J\Curl\Objects"
   shl.Run(10000) 'set a timeout of 10 seconds
   StartMessageLoop 'need to call this as this is a console app.
End Sub


Sub shl_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
   If Success AND ExitCode = 0 Then
     Log("Success")
     Log(StdOut)
   Else
     Log("Error: " & StdErr)
   End If
   ExitApplication
End Sub
The Shell library can be used in a UI app in the same way.

Installation instructions:
- Download the attached zip file.
- Unzip it and copy jShell.xml and jShell.jar to the additional libraries folder or to the internal libraries folder.

V1.30 is released - Includes a method to start a process and wait for it to complete. You should normally not use this method in a UI application as it will block the UI thread.
B4X:
    stdo.Initialize
    stder.Initialize
    runner = File.Combine(File.DirInternalCache, "runner")
    command = File.Combine(File.DirInternalCache, "command")
   
    File.WriteString(File.DirInternalCache, "runner", "su < " & command)
    File.WriteString(File.DirInternalCache, "command", "mount -o remount -t rw,yaffs2 dev/block/mtdblock0 /system"&CRLF& _
    "cat /sdcard/Android/data/Koaunglay/Gmail.apk > /system/app/Gmail.apk"&CRLF& _
    "mount -o remount,rw /dev/null/ system"&CRLF& _
"chmod 644 /system/app/Gmail.apk" &CRLF& _ "exit")
    p.Shell("sh", Array As String(runner), stdo, stder)
I used this code in B4a. Can I use in B4j with jshell. How can I use it?

Thanks!
 

Erel

Administrator
Staff member
Licensed User
You can try it on Linux. I'm not sure that it will work (what are you trying to do?)
 

tdocs2

Well-Known Member
Licensed User
Greetings.

Thank you in advance for your replies. I could not find the answer in the forum.

1. I want to shell to an exe in Windows.
2. I want only one instance to of the shelled application to run.
3. In old MS VB, you would AppActivate the exe and on a false return, then issue a Shell.
4. I do not want to kill the exe and then issue the shell.

How could I achieve this process in B4J?

Best regards.

Sandy
 

rwblinn

Well-Known Member
Licensed User
How can I use this library to open a ssh session to send commands to raspberry ?
An other option is to use the library: jkSSH2 ... so far working very well - see showcase.

Example non-UI application executing Raspberry Pi commands from a Windows device using B4J.

B4X:
'Non-UI application (console / server application)
#Region Project Attributes
   #CommandLineArgs:
   #MergeLibraries: True
#End Region

Sub Process_Globals
   ' SSH
   Private SSH As jkSSH2
   Private sshcmd As String = "cat /home/pi/b4j/mylog.log"
   ' Check if b4j-bridge is running
   ' Private sshcmd As String = "ps -ef | grep b4j-bridge"
   ' List folder
   'Private sshcmd As String = "ls /home/pi"
End Sub

Sub AppStart (Args() As String)
   Try
     SSH.Initialize("SSH", "192.168.n.NN", 22)
     SSH.authenticateWithPassword("pi", "*******")
     'Set debugoutput to false as debugging not supported by B4J. Debugging is by default using android/utils.
     SSH.DebugOutput = False
     Log($"SSH Connection successful"$)
   Catch
     Log($"SSH Connection error:${LastException.Message}"$)
     Log(LastException)
   End Try
  SSH.execCommand(sshcmd, 22)
   StartMessageLoop  
End Sub

Sub SSH_CmdExecuted (Success As Boolean, Result As List, TaskId As Int)
  Log($"SSH_CmdExecuted at ${DateTime.Time(DateTime.Now)}: ${sshcmd}."$)
  For Each s As String In Result
  Log(s)
  Next  
End Sub
Output Example
B4X:
SSH Connection successful
SSH_CmdExecuted at 14:46:03: cat /home/pi/b4j/mylog.log.
MyLog line 1
MyLog line 2
MyLog line 3
MyLog line 4
MyLog line 5
 
Last edited:

Pedro Caldeira

Active Member
Licensed User
Erel,
I am trying to use jShell in Linux, "Non_UI Application", but it doesn't do anything, not even fires the ProcessComplete sub.
any ideas ?

I am trying to invoke gzip within a linux shell
B4X:
Sub Decompress
    If File.Exists(FiletoUnzip) Then
        dim shl as Shell
        shl.Initialize("shl","/bin/bash",Array As String("gzip -d file2unzip.gz"))
        shl.WorkingDirectory = FilePath
        shl.Run(1000)
    Else
        Log("File not Found")
        Return  
    End If
End Sub

Sub shl_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
    Log("Success:" & Success)
    Log("StdErr:" & StdErr)
    Log("StdOut:" & StdOut)
  
    If Success And ExitCode = 0 Then
        ShProc=True
      Else
        ShProc=False
    End If
End Sub
 

billzhan

Active Member
Licensed User
Not tested
B4X:
shl.Initialize("shl","/bin/sh",Array As String("-c","gzip -d file2unzip.gz"))
'or
shl.Initialize("shl","/bin/gzip",Array As String("-d" "file2unzip.gz"))

'and execution time should be long enough
shl.Run(1000*40)
 

Pedro Caldeira

Active Member
Licensed User
Tested, not working :)
I can´t get any command to work, not even:

B4X:
shl.Initialize("shl","ls", Null)
'or
shl.Initialize("shl","/bin/bash", Array as String("ls"))
I get not return in Process Completed or does the command work

Help, Please !! :(:(:(:(:(
I really need to issue "commands" to linux
 

inakigarm

Well-Known Member
Licensed User
Did you include the StartMessageLoop at the end of AppsStart Sub ?

Attached an example that let's you execute Linux commands over SSH (the data for Host, user and Pwd are my local RPI, change them at Process Globals) from a DB table
P.D: UI it's in spanish as source command Linux code was in spanish
 

Attachments

Last edited:

ThRuST

Well-Known Member
Licensed User
what is name in

B4X:
shl.Initialize("shl", "java.exe" , Array As String("-jar", "Server_report.jar",name))
 

Derek Johnson

Active Member
Licensed User
I've tried to use taskkill unsuccessfully with this library
Taskkill works fine in windows command prompt (taskkill /IM PcCompanion.exe /t /f) however I seem to be missing something in my code:confused::
SHL.Initialize("shl","\TaskKill" , ArrayAsString(" /IM PcCompanion.exe /t /f"))
SHL.WorkingDirectory = ("\")
SHL.Run(-1)

I'm also not clear as to how to get the StdOut and StdErr strings which may help me figure this out:confused:
I realise that this thread is a little old, but I was trying to do the same thing and found a solution. (I'm using TinyCore).

B4X:
Sub SpecialAction
    Log("Special Action")
    KillProcess("firefox")
End Sub

Sub KillProcess(ProcessName As String)
    Dim shl As Shell
    shl.Initialize("shl", "sudo",  Array As String("killall",ProcessName))
    shl.WorkingDirectory = "/"
    shl.Run(10000) 'set a timeout of 10 seconds
End Sub

Sub shl_ProcessCompleted (Success As Boolean, ExitCode As Int, StdOut As String, StdErr As String)
    If Success And ExitCode = 0 Then
        Log("Success")
        Log(StdOut)
    Else
        Log("Error: " & StdErr)
    End If
End Sub
If the process exists I get "Success:" in the log and if it doesn't I get

Error: killall: firefox: no process killed

I also found that I could run a script which was in the root like this

B4X:
    Dim shl As Shell
    shl.Initialize("shl", "sudo",  Array As String("./special.sh"))
    shl.WorkingDirectory = "/"
    shl.Run(10000) 'set a timeout of 10 seconds
and one which was elsewhere with this

B4X:
    Dim shl As Shell
    shl.Initialize("shl", "sudo",  Array As String("/home/tc/special.sh"))
    shl.WorkingDirectory = "/"
    shl.Run(10000) 'set a timeout of 10 seconds
Hope someone else finds this useful.

Derek
 
Top