Launch Persistent Shell

Got a LiveCode personal license? Are you a beginner, hobbyist or educator that's new to LiveCode? This forum is the place to go for help getting started. Welcome!

Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller

Post Reply
studawg66
Posts: 25
Joined: Wed Jun 17, 2015 9:40 pm

Launch Persistent Shell

Post by studawg66 » Wed Sep 22, 2021 10:04 pm

I have an external script that I want to trigger on openStack, but the cmd (shell) window needs to stay open. If I run this executable outside of LC, the cmd window stays open because of my input command, so it says "Press enter to exit" and awaits that key stroke.
But whenever I do a "get shell(myScript)" in LC it launches the command line utility but then immediately closes it. Is there a way to keep that cmd window open, awaiting the input request?

Bernard
Posts: 351
Joined: Sat Apr 08, 2006 10:14 pm
Location: London, England

Re: Launch Persistent Shell

Post by Bernard » Fri Sep 24, 2021 10:06 am

Why can't I reply to this. My reply (with sample code) always fails to be accepted by the forum software.

Bernard
Posts: 351
Joined: Sat Apr 08, 2006 10:14 pm
Location: London, England

Re: Launch Persistent Shell

Post by Bernard » Fri Sep 24, 2021 10:09 am

studawg66 wrote:
Wed Sep 22, 2021 10:04 pm
I have an external script that I want to trigger on openStack, but the cmd (shell) window needs to stay open. If I run this executable outside of LC, the cmd window stays open because of my input command, so it says "Press enter to exit" and awaits that key stroke.
But whenever I do a "get shell(myScript)" in LC it launches the command line utility but then immediately closes it. Is there a way to keep that cmd window open, awaiting the input request?

Code: Select all

get shell("start x /K dir "); put the long time
(replace x with cmd dot exe above)

will open a terminal window and list the files in that directory (the defaultFolder). The terminal window will have focus.

I'm not clear if you want to stop execution of your code whilst you are waiting for the user to interact with your terminal window. In the above case LC will continue processing (as evidenced by the long time appearing in the message box.

Bernard
Posts: 351
Joined: Sat Apr 08, 2006 10:14 pm
Location: London, England

Re: Launch Persistent Shell

Post by Bernard » Fri Sep 24, 2021 10:10 am

it looks like the characters "cmd dot exe" are banned by the forum software.

studawg66
Posts: 25
Joined: Wed Jun 17, 2015 9:40 pm

Re: Launch Persistent Shell

Post by studawg66 » Fri Sep 24, 2021 5:48 pm

Thanks, Bernard!
I was able to make a slight modification to your suggestion and it worked like a charm!
I added the "min" flag to minimize the cmd window as soon as it launches, so that gets it out of the way and lets it do its thing.

Code: Select all

get shell("start /min x /k C:/temp/myprogram dot exe")
where x is cmd dot exe

studawg66
Posts: 25
Joined: Wed Jun 17, 2015 9:40 pm

Re: Launch Persistent Shell

Post by studawg66 » Fri Sep 24, 2021 9:32 pm

I thought this next step would be easy but I'm struggling. How would I close out this cmd window on closing the LC application?
I tried several things in the "closeStack" routine, like:

Code: Select all

put shell("exit")

Code: Select all

put shell("cmd-dot-exe exit")
...and some other iterations of that. But I can't seem to find a way to make it happen. Is this possible? Is there a way to pass more information to that open cmd instance after the initial "start" command has been run? Like an enter key, or an exit command?

FourthWorld
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 9802
Joined: Sat Apr 08, 2006 7:05 am
Location: Los Angeles
Contact:

Re: Launch Persistent Shell

Post by FourthWorld » Fri Sep 24, 2021 9:40 pm

In the Linux shell you can append a command with & to return control to the parent process.

I don't know the shell syntax for that on Windows, but maybe easier to just use the "open process" command with the "for neither" option.
Richard Gaskin
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn

mtalluto
VIP Livecode Opensource Backer
VIP Livecode Opensource Backer
Posts: 125
Joined: Tue Apr 11, 2006 7:02 pm
Location: Seattle, WA
Contact:

Re: Launch Persistent Shell

Post by mtalluto » Fri Sep 24, 2021 10:37 pm

I have used: [start /b] to manage running extra processes. This method does not run the app in another window. It feels more like a deamon.

https://ss64.com/nt/start.html
Mark Talluto
--
Canela
design - develop - deploy: https://appli.io
Database and Cloud for LiveCode Developers: https://livecloud.io
Company: https://canelasoftware.com

Bernard
Posts: 351
Joined: Sat Apr 08, 2006 10:14 pm
Location: London, England

Re: Launch Persistent Shell

Post by Bernard » Sat Sep 25, 2021 12:03 pm

studawg66 wrote:
Fri Sep 24, 2021 9:32 pm
I thought this next step would be easy but I'm struggling. How would I close out this cmd window on closing the LC application?
I tried several things in the "closeStack" routine, like:

Code: Select all

put shell("exit")

Code: Select all

put shell("cmd-dot-exe exit")
...and some other iterations of that. But I can't seem to find a way to make it happen. Is this possible? Is there a way to pass more information to that open cmd instance after the initial "start" command has been run? Like an enter key, or an exit command?
I'm not aware of anyway to use Windows taskkill with the "title" given to a cmd-dot-exe instance. You would need the process ID to target a specific window (you could perhaps just get a list of all cmd-dot-exe PIDs and kill them all with Windows

Code: Select all

tasklist|find "cmd-dot-exe"
, but that would be a very unfriendly thing to do to users of your application.

Perhaps what you need is "open process" rather than shell() -- see the LC Dictionary. Once another exe is opened via open process you can write to it/read from it then call "close process" when you have finished.

Shell() is the simple/limited way to do things. Open process is more powerful but also can be more complicated.

Bill
Posts: 57
Joined: Sat Apr 08, 2006 8:22 pm

Re: Launch Persistent Shell

Post by Bill » Sat Sep 25, 2021 2:04 pm

Code: Select all

-- a file to pipe output to
   put "%userprofile%/Documents/myCommand.txt" into tFile 
   
   -- set up your command window title
   put quote & "MyCommandWindow" & quote into myTitle
   
   --build your command in a string  
   put "start <Your_Program.exe> & title" && myTitle && "& tasklist /v /fo csv | findstr /i" && myTitle &&">>" && tFile  into tCom
   get shell(tCom)
Then item 2 of the file is the PID with quotes.
You probably want to set that file path up entirely with Livecode so you can access it for read directly.

studawg66
Posts: 25
Joined: Wed Jun 17, 2015 9:40 pm

Re: Launch Persistent Shell

Post by studawg66 » Mon Sep 27, 2021 8:00 pm

Thanks for these responses! I have tried a couple of the suggestions but it is not accomplishing what I'm looking for. I think it would help if I provided more detail on what I'm doing.
I built an external executable that disables the Windows screensaver by wrapping the following python code in an exe:

Code: Select all

import ctypes
ctypes.windll.kernel32.SetThreadExecutionState(0x80000002)
input('{Screensaver has been DISABLED. Press Enter or close this window to enable it.}')
The input line was required to keep the thread open, because if the script just runs and closes the thread (returns to the prompt or closes the window), that ThreadExecutionState returns to its default value and the screensaver is enabled again.
So I have the following in Livecode in the openStack routine to run this script:

Code: Select all

get shell("start /min cmd-dot-exe /k C:/temp/SleepDisable-dot-exe")
This runs that script, keeps it active, and immediately minimizes it to get it out of the way of my Livecode GUI.

It works, but I would like to be able to clear things out when I close Livecode. Right now the only way is to close Livecode then go close that cmd window manually. Not a huge deal but if there was some way to interact with that open cmd window or to kill it, that would clean things up for the end user and not have screensavers permanently disabled by 17 open cmd windows :D

Ideally, I would love for Livecode to directly access that "kernel32.dll" SetThreadExecutionState function without need of this external cmd window, but I've asked that elsewhere on these forums and received no response. So if you have any ideas there, I'm all ears!
I hope this makes more sense.

Bernard
Posts: 351
Joined: Sat Apr 08, 2006 10:14 pm
Location: London, England

Re: Launch Persistent Shell

Post by Bernard » Wed Sep 29, 2021 12:48 pm

Assuming you STARTed the program and set the title of that process to (say) _MyTitle_ you should be able to kill off the hidden process when you close your own app using

Code: Select all

put "_MyTitle_" into tTitle
put quote into q
shell(  merge( "taskkill /FI [[q]]WINDOWTITLE eq [[tTitle]][[q]]" )  )
I just tried killing a process this way and it worked. Let us know if it doesn't work for you.

You may have to use this version:

taskkill /F /FI "WINDOWTITLE eq _MyTitle_"

where /F means "force closure".

studawg66
Posts: 25
Joined: Wed Jun 17, 2015 9:40 pm

Re: Launch Persistent Shell

Post by studawg66 » Wed Sep 29, 2021 8:07 pm

Ah, yes. Naming the task! This worked perfectly!

To summarize, I disable the screensaver by calling my "SleepDisable.exe" program and NAME it "SleepDisable" for future, using the "/min" to minimize the window immediately, and the "/k" parameter to keep the window open, which keeps my SleepDisable function running:

Code: Select all

get shell("start /min " & quote & "SleepDisable" & quote & " cmd-dot-exe /k " & quote & myFilePath & quote)
Then, on a closeStack request, I run the following, which looks for open processes called "SleepDisable" and kills them:

Code: Select all

get shell("taskkill /FI " & quote & "WINDOWTITLE eq SleepDisable*" & quote)
Works like a charm! Thanks again for getting me on the right track.

Post Reply

Return to “Getting Started with LiveCode - Complete Beginners”