Launch Persistent Shell
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller
Launch Persistent Shell
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?
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?
Re: Launch Persistent Shell
Why can't I reply to this. My reply (with sample code) always fails to be accepted by the forum software.
Re: Launch Persistent Shell
studawg66 wrote: ↑Wed Sep 22, 2021 10:04 pmI 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
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.
Re: Launch Persistent Shell
it looks like the characters "cmd dot exe" are banned by the forum software.
Re: Launch Persistent Shell
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.
where x is cmd dot exe
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")
Re: Launch Persistent Shell
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:
...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 tried several things in the "closeStack" routine, like:
Code: Select all
put shell("exit")
Code: Select all
put shell("cmd-dot-exe exit")
-
- VIP Livecode Opensource Backer
- Posts: 9867
- Joined: Sat Apr 08, 2006 7:05 am
- Location: Los Angeles
- Contact:
Re: Launch Persistent Shell
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.
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
LiveCode development, training, and consulting services: Fourth World Systems
LiveCode Group on Facebook
LiveCode Group on LinkedIn
-
- VIP Livecode Opensource Backer
- Posts: 125
- Joined: Tue Apr 11, 2006 7:02 pm
- Location: Seattle, WA
- Contact:
Re: Launch Persistent Shell
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
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
--
Canela
design - develop - deploy: https://appli.io
Database and Cloud for LiveCode Developers: https://livecloud.io
Company: https://canelasoftware.com
Re: Launch Persistent Shell
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 Windowsstudawg66 wrote: ↑Fri Sep 24, 2021 9:32 pmI 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")
...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?Code: Select all
put shell("cmd-dot-exe exit")
Code: Select all
tasklist|find "cmd-dot-exe"
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.
Re: Launch Persistent Shell
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)
You probably want to set that file path up entirely with Livecode so you can access it for read directly.
Re: Launch Persistent Shell
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:
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:
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
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.
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.}')
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")
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
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.
Re: Launch Persistent Shell
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
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".
Code: Select all
put "_MyTitle_" into tTitle
put quote into q
shell( merge( "taskkill /FI [[q]]WINDOWTITLE eq [[tTitle]][[q]]" ) )
You may have to use this version:
taskkill /F /FI "WINDOWTITLE eq _MyTitle_"
where /F means "force closure".
Re: Launch Persistent Shell
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:
Then, on a closeStack request, I run the following, which looks for open processes called "SleepDisable" and kills them:
Works like a charm! Thanks again for getting me on the right track.
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)
Code: Select all
get shell("taskkill /FI " & quote & "WINDOWTITLE eq SleepDisable*" & quote)