External files

Q:

Is it possible to export a lianja .dbf file back into a vfp .dbf file. We need to copy some data into legacy vfp software to keep our system functioning while software is getting rewritten. — can’t seem to delete the post, but found that I could export the data using a text file.

A:

There are several ways to do this. If this is a one off, then use the copy command with a delimited type. Then import that into your VFP table.

http://www.lianja.com/doc/index.php/COPY

If this is something you plan to do often, then probably setting up an ODBC conncetion to lianja makes the most sense.
http://www.lianja.com/doc/index.php/…ver_on_Windows


Lianja provides tight integration with the command shell. The ` … ` command sequence (backticks) can be used to run external shell commands that are piped together and to substitute the output into a Lianja character string.

After select/copy/paste these examples in Console workspace on usual Windows:
Code:

? "`cmd /c date /t`"    // works OK

? "Date is `date`"     // does not work

Barry uses cygwin and both commands work for him.
If it is not easy to find backtick on the keyboard, the code for backtick is ALT+96

I’ve tested the proper formatted commands using back ticks and they work as expected.

On further investigation I’ve found that it appears that when I “run cmd” from Lianja, it is cmd.exe that is hanging. Lianja is simply waiting for cmd.exe to finish. If I shut down cmd.exe from task manager, Lianja continues just fine.

So the crash is definitely an issue with my system and, as you say, since I have no reason to ever need to this in my code, it’s not even an issue.

I have simplified this behavior on Windows in Lianja 3.4RC14. You now no longer need to specify cmd /c you can just use the backticks but remember that the command itself must be a valid windows command that produces output.

? “The date is `date /t`”


Q:

with Lainja.SpawnApp() I can call other app.

EG: lianja.SpawnApp(“lianjademo”), start the app, but the deployed app, not the “building app”.

Can I set the window size of the opened app?

A:

Lianja.spawnApp() only takes an app name not command line args.
https://www.lianja.com/doc/index.php/Lianja

You should use spawn() or run() if you want to specify command line args.

A2:

run(“C:\lianja\bin\lianjaruntime.exe –utf8 –debug –nosplashscreen –app sampleproductsentry –geometry 10,10,800,600”)

and it work.. 🙂

so, I can:

Code:
Lianja.sessionStorage.setItem("p_retvalue", False)
run("C:\lianja\bin\lianjaruntime.exe --utf8 --debug --nosplashscreen --kiosk --app sampleproductsentry --geometry 10,10,800,600")
value = Lianja.sessionStorage.getItem("p_retvalue")	
messagebox(etos(Value))

in my “sampleproductsentry” app I do:

Code:
Lianja.sessionStorage.removeItem("p_retvalue")
Lianja.sessionStorage.setItem("p_retvalue", PRODUCTS.PRODUCTID)
Lianja.closeApp()
quit

from the first app, I call the second, when the user close it, the control return to the first and I can read the value passed.


Q:

Lianja.spawnApp conveniently allows running a .dbo (compiled prg) directly, as so:

lcDbo = “myprg.dbo”
lcPathedDbo = set(“dire”) + lcDbo
Lianja.spawnApp(lcPathedDbo)

Here’s the challenge: I’m launching this from a web service (.rsp page application/json), and need to have the .dbo accept a parameter so that it processes a particular instance based on data pointed to by the parameter.

Although SessionStorage might look like an answer, that has the same issue: I would need to communicate the “key” for the .dbo to access.

A:

You cannot use Lianja.spawnApp() from a server page. The Lianja system object is only available in the clients I.e desktop, web or mobile.

Lianja.spawnApp() is desktop specific as it relies on being called from the lianja runtime client.

Rather than spawning a process from inside a web service I’d recommend you implement a consumer/producer architecture which will be much more scaleable.

See my post in these forums on resource locks.

You could add request records to a table in the web service always locking a known resource exclusively beforehand.

You then have a background job (using cron on linux or task scheduler on Windows) running that reads records from the table and processes the requests. When there are no more requests, lock a known resource and zap the table then unlock the resource.


 

Advertisements

External files

Q:
Using (Foxpro) functions filetostr and strtofile to read and write a specific file (f.e. e:\xxx\yyy\z.txt) on my server is ok in DeskApp but not in WebApp.
Error message: File not exists. Error number: 15
Is it not possible to use these functions in a Webapp?
A:
filetostr() will run where the code runs, which is on the server, not on the client. Could that be the issue?

You can upload a file using networkrequest (http://www.lianja.com/community/show…load-in-Lianja) Here’s a thread for further reference: http://www.lianja.com/community/arch…hp/t-3027.html

Note that you can upload a file from the user’s desktop into a data file using the Attachments section, and then can run filetostr() on the memofield using mtos() .
assuming you have deployed the app to the server on the APaaS, and are calling the filetostr() through a call on the server (using Lianja.evaluate() from the JavaScript, or using an .rsp page) there should be no issue.


Q:
I would like to store some text from a .txt file to a memory variable. Below is what I did, but It does not work. invmemo still does not have the string from the text file. Any suggestions.

Code:
...
ans = messagebox("Do you want to add a memo to the invoice?", 36, "ADD MEMO")
if ans = 6
memofilename=GETFILE('txt',"","",2,'Add a .txt file to memo')
invmemo = filetostr(memofilename)
endif

A:

Code:
REPLACE invmemo with filetostr(memofilename)
//or
APPEND MEMO invmemo FROM memofilename

Q:
Is it possible to get a return value from a run or spawn command
A:
Yes, using spawnid() etc. you can know when the process ends.
So, the spawned
process writes to SessionStorage, and the calling process picks up the result from SessionStorage.


Q:
What would be a step by step to create a Lianja windows service?
A:
Method 1: .bat file calling app with lianjaruntime.exe –app appname Run as Windows Scheduled Task, set to run on startup, with highest permissions.

Method 2: srvany.exe — blog post by Calvin Hsai here: http://blogs.msdn.com/b/calvin_hsia/…13/282351.aspx


I have an older VFP App where I use the run command to run some background processes. I have replaced them with the Lianja spawn command

The Spawn command uses the same syntax as the run command.
Spawn will run your process in the background and return control of your app back to while it is running.

Thats very handy if you need to run simultaneous operations while not relinquishing control of your application.
1) if you are running a lot of processes, you can end up overloading the processor and hurting UI performance. This would especially be the case if you were running a Lianja Desktop App on a remote desktop-type (RDP or ICA) environment.
2) you can monitor what processes you have running by getting the pid of a spawned process using ActivePid().
3) If you do have a cajillion background processes to run, you can run the spawn off a web service call to another server where the Lianja Cloud Server is running. Maintaining a central database with server and pid will allow you to coordinate all this.
4) You can get return values in a variety of ways. SharedMemory is one way (google Lianja Shared Memory). Another way is to the use monitoring database table entry for a given server and pid to hold the return value.


Q:
In my program, I have a canvas section with a command button.
When the button is clicked, I access a local database then transfer the rows of data to an excel sheet.
So far it’s all working fine except for the processing speed.
It starts off by processing approx. 4 rows every second. Shortly afterwards, the process slows down.

Code:
scan
  scatter to ExcelExport
  WITH oExcel
    .Range("A" + ALLTRIM(str(excelRowCount))).Value = ALLTRIM(LNAME)
    ...
  ENDWITH

  // Activate another table
  select ...
  append blank
  gather FROM ExcelExport
  replace DATEARCHIVED with date()
  skip 0
               
  excelRowCount = excelRowCount + 1
  progBarCount = progBarCount + 1
  Lianja.Get("page.section.pbExport").value = progBarCount
endscan

A:
If excel is indeed the issue, see if you can issue one command to excel that exports the data you need in csv format (or even ado-style xml). Exporting that will be a quick task, as will importing into a cursor in Lianja. From there, things should fly.
“winner” code which execute almost instant:

Code:
proc page1_section1_field2_click()
        cDirSelected = getdir("C:\","","Please Select A Directory For File Saving")
        IF inuse("exceldata") = .T.
            SELECT exceldata
        ELSE
            select 0
            use exceldata
        ENDIF
        cDateTime = ttoc(datetime(),1)
        if right(cDirSelected,1)  "\"
            cDirSelected = cDirSelected + "\"
        endif
        cSaveAsPath = cDirSelected + "ExcelExport_" + cDateTime + ".txt"
       
        set textmerge to (cSaveAsPath)
        set textmerge delimiters to "{{","}}"
        set textmerge on
        c9=chr(9)
        scan
\{{DLNAME}}{{c9}}
\\{{DFNAME}}{{c9}}
\\{{CLNUM}}{{c9}}
\\{{DTYPE}}{{c9}}
\\{{DADDR1}}{{c9}}
\\{{DADDR2}}{{c9}}
\\{{DADDR3}}{{c9}}
\\{{DCITY}}{{c9}}
\\{{DPROVINCE}}{{c9}}
\\{{DPCODE}}{{c9}}
\\{{DCOUNTRY}}


 

External files

Q:
I would like to access a file saved in a folder that is in the app folder.
How would I access the app path?

For example, say file abc.xls exists in an Excel folder.
The development path could be:
C:\Lianja\apps\testing\Excel\abc.xls.

I could use the following:

Code:
oExcel = CREATEOBJECT("Excel.application")
// Need help here.
cExcelPath = app.path + "\Excel\abc.xls"
oWorkbook = oExcel.Workbooks.Open(cExcelPath)

A:
DEFAULT() or even SYS(2003) should do it for you.



External files

RUN executes a command line without capturing it’s output, waits for command completion

SPAWN
executes a command line without capturing it’s output. Starts the command and continues execution in parallel

PIPETOSTR()
executes a command line capturing and returning whatever it wrote to its standard output, waits for completion.
Bacticks can be used inside character strings to capture the output and substitute into the character string

SHELLEXEC
is a windows only and non portable WINAPI function call

Also note that you can execute a program via file association e.g. To open up PDF file.

Code:
Lianja.showDocument("myfile.pdf")

When including the full path to a file please include “file:///“. For example:

Code:
showdocument("file:///f:\staff\sherlie\book2.xlsx")

One way is to use the RUN command:

Code:
RUN "c:\windows\EXPLORER.EXE /n, /e, X:\Folder_of_my_choosing"

 

Code:
WSHShell = CreateObject("WScript.Shell")
eExe = WSHShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\AcroRd32.exe\")
if type("eExe") = "C"
        ? "Key exists: " + eExe
else
        ? "Key not found"
endif
RELEASE WSHShell

 


Is it actually a specific file you need to open? Is it a scenario where you could create a temporary file (TMPNAM() will give you a temporary file name in the temporary files directory) so that multiple users aren’t trying to access the same file?
If it’s the CSV report files we are talking here and the CSV is already open in Excel, the fopen() will return a filehandle of -1, ferror() will return -1, errno() will return 13 and strerror(errno()) will return ‘Permission denied’. That doesn’t tell you who has the file open, or whether the ‘Permission denied’ is due to another cause.


Q:
What would be good way to run an executable? Ping. Pipe (Linux)
A:
From the Linux desktop you could use ! and output to a file, then handle the file e.g.

Code:
!ping -c 5 192.168.3.3 > /home/yvonne/ping.txt
type /home/yvonne/ping.txt

 


When creating a new window that runs an App the –args “arg” that you specify is in the same format as Lianja.showDocument() NOT args to a script.
So for example to load the “customerorders” app and lookup the customerid.

Code:
Lianja.spawnApp("c:\lianja\bin\lianjaruntime --app mysalesapp --args "page:customers?action=search&text=1220")

Excel file formats are different between older and newer releases and I am unsure what version of excel you are using so you need to research the ODBC driver that matches the version you use.
Be aware that excel is not multiuser either so you need to bear this in mind if you are building a multiuser application that interacts with an excel spreadsheet.


Q:
Is it possible to call a Windows command-line application from within a Lianja App?
A:

Code:
Lianja.run("path_to_exe","arg1,arg2...")

or

Code:
Lianja.spawn("path_to_exe","arg1,arg2...")

Q:
The reason I ask is that I can call a prg with it and get no error; but there is also no evidence that the prg is running. Executing

Code:
? lianja.spawnapp("testspawn.prg")

A:
In fact I stand corrected, my code will run .prg, .php, .py. .js and app files.
You may need to set the path of the filename if its not an App.

Code:
result = Lianja.spawnApp(filename | appname, [username, [password, [args] ] ])
if result
  // process is running
endif

Lianja.showDocument() has some interesting functionality that is not well known.
You can
invoke the desktop browser,
run external applications,
run other apps (in a new runtime container)
and also
run Lianja/VFP scripts (in a new runtime container).
Lianja.showDocument() handles desktop associations. e.g..

Code:
Lianja.showDocument("http://www.google.com")
Lianja.showDocument("myspreadsheet.xlsx")
Lianja.showDocument("myspecialapp.exe")
Lianja.showDocument("lianja --app myapp --username myusername --password mypassword")
Lianja.showDocument("lianja myform.prg")