Android Question jcifs-ng SMB-Client

Similar threads

B4A Library jcifs-ng SMB-Client (SMB2)
B4A Library DonManfreds Overview
B4A Tutorial Android SMB / CIFS tutorial
B4A Question Problem with jcifs-ng library
B4A Library SMB library

Lars Andersson

Member
Licensed User
Have been playing with "DonManfred's" library with some success.
So far I have been able to read and list files but to create a file using SMB is a different story.
Does anyone have sample code that I can start with?

Lars
 

DonManfred

Expert
Licensed User
but to create a file using SMB is a different story
true. The problem is that every access to a smbresource needs networktraffic. So, methods like exists, createfile, getting input- or outputstream can not be used easily.

This can work.

B4X:
    smbClient.GetResourcefromUrl("smb://192.168.192.168/GeoTIFs/") ' getting a reference to a resource where you want to create a new file.
    wait for SMBClient_Resource(success As Boolean, smbobjres As Object,smbobj As Object, info As String)
    Log($"writetest-SMBClient_Resource(${success},${info},${smbobjres},${smbobj})"$)
    If smbobjres <> Null And smbobj <> Null And info = "OK" Then
        Dim smbResource As SMBResource = smbobjres ' the resource object pointing to smb://192.168.192.168/GeoTIFs/
        Dim sfile As SMBFile = smbobj
        File.WriteString(File.DirInternal, "1.txt", "Some text") ' write what you want to write to a file in File.Dirinternal.
        smbClient.Copy2(File.DirInternal,"1.txt",sfile,"textfile.txt") ' Copy the file to the SMBFile reference (also pointing to smb://192.168.192.168/GeoTIFs/). The content of File.Dirinternal\1.txt is written to textfile.txt in the resource smb://192.168.192.168/GeoTIFs/
' in fact it is creating the resource smb://192.168.192.168/GeoTIFs/textfile.txt
    End If
 

Lars Andersson

Member
Licensed User
Thanks a lot Manfred!

As I'm a "hobby programmer" I failed already in the "first row" in your sample code :-(

B4X:
Sub INspecbutton_Click

    CreateFile("smb://192.168.1.17/share/Test/", "1.txt", "Test")

End Sub

Sub CreateFile(Url As String, Fil As String, Txt As String)

    smbClient.GetResourcefromUrl(Url) ' getting a reference to a resource where you want to create a new file.

    'smbClient.GetResourcefromUrl("smb://192.168.192.168/GeoTIFs/") ' getting a reference to a resource where you want to create a new file.
    
    wait for SMBClient_Resource(success As Boolean, smbobjres As Object,smbobj As Object, info As String)
    Log($"writetest-SMBClient_Resource(${success},${info},${smbobjres},${smbobj})"$)
    
    If smbobjres <> Null And smbobj <> Null And info = "OK" Then
        Dim smbResource As SMBResource = smbobjres ' the resource object pointing to smb://192.168.192.168/GeoTIFs/
        Dim sfile As SMBFile = smbobj
        
        File.WriteString(File.DirInternal, Fil, Txt) ' write what you want to write to a file in File.Dirinternal.
        
        'File.WriteString(File.DirInternal, "1.txt", "Some text") ' write what you want to write to a file in File.Dirinternal.
        'smbClient.Copy2(File.DirInternal,"1.txt",sfile,"textfile.txt") ' Copy the file to the SMBFile reference (also pointing to smb://192.168.192.168/GeoTIFs/). The content of File.Dirinternal\1.txt is written to textfile.txt in the resource smb://192.168.192.168/GeoTIFs/
        ' in fact it is creating the resource smb://192.168.192.168/GeoTIFs/textfile.txt
    End If
    
End Sub

Error thrown....
java.lang.NullPointerException: Attempt to invoke interface method 'jcifs.SmbResource jcifs.CIFSContext.get(java.lang.String)' on a null object reference
at de.donmanfred.SMBClientwrapper$6.run(SMBClientwrapper.java:308)
at java.lang.Thread.run(Thread.java:761)

Lars
 

DonManfred

Expert
Licensed User
the client is initialized with the correct credentials?

B4X:
Sub btn_Init_Click
    Log($"Domain = ${edt_Domain.Text.Trim}"$)
    Log($"Username = ${edt_Username.Text.Trim}"$)
    Log($"Password = ${edt_Password.Text.Trim}"$)
    Log($"Share = ${edt_Share.Text.Trim}"$)
    
    
    Dim credentials As SMBCred
    credentials.Initialize
    credentials.Domain = edt_Domain.Text.Trim
    credentials.Username = edt_Username.Text.Trim
    credentials.Password = edt_Password.Text.Trim
    credentials.Share = edt_Share.Text.Trim
    
    CallSub2(Starter,"SMBInit",credentials)

End Sub
and in my case in starter

B4X:
Sub SMBInit(cred As SMBCred)
    smbClient.Initialize("SMBClient",cred.Domain,cred.Username,cred.Password,cred.Share)
    smbClient.GetResourcefromUrl("smb://192.168.192.168/GeoTIFs/")
    wait for SMBClient_Resource(success As Boolean, smbobjres As Object,smbobj As Object, info As String)
    Log($"writetest-SMBClient_Resource(${success},${info},${smbobjres},${smbobj})"$)
    If smbobjres <> Null And smbobj <> Null And info = "OK" Then
        Dim smbResource As SMBResource = smbobjres
        Dim sfile As SMBFile = smbobj
        File.WriteString(File.DirInternal, "1.txt", "Some text")
        smbClient.Copy2(File.DirInternal,"1.txt",sfile,"textfile2.txt")
        wait for SMBClient_CopyResult(success As Boolean, path As String, filename As String)
        Log($"SMBClient_CopyResult(${success}, textfile2.txt written to ${sfile.UncPath})"$)
    End If
End Sub
Sub SMBClient_ResourceAvailable(smbResource As Object)
    Log($"SMBClient_ResourceAvailable(${smbResource})"$)
End Sub
Sub SMBClient_CopyProgress(totalBytes As Long, path As String, filename As String)
    Log($"SMBClient_CopyProgress(${totalBytes} : ${path}:${filename})"$)
End Sub
 

Lars Andersson

Member
Licensed User
Seems like I got it to work....
I had to Initialize again as my sub wasn't in "Starter".
You learn from your mistakes I guess ;-)

Thanks a lot for taking you time, really appreciated!
 

Lars Andersson

Member
Licensed User
What is the best practice to know that the share is avalible and kept Initialized/alive?
My "sort of issue" is that it takes pretty long time to Initialize every time I need to access the share so I would like to avoid it.
Also, how to handle a lost connection?
 
Top