Jump to content

Re-using the command line interface


Recommended Posts

I have an app that needs to communicate via the CMD, I think that every call into the CMD is causing quite some overhead. Does anybody know how I can keep a CMD reference open and execute commands in it, and read the output?

Ton

Link to post
Share on other sites

Hmm. Is using CMD a necessity or a crutch? You could create the target process yourself and read its output using pipes (or a slightly denser example from Microsoft).

You can use the console functions to create a console and then read/write at will, but I'm not sure how easy it is to make that console a shell session.

Edited by asbo
  • Like 1
Link to post
Share on other sites

Do you need to execute, read, execute, read, etc, or can you run a bunch of commands in a batch file and then read the output when it completes?

K.I.S.S. award goes to ...

Link to post
Share on other sites

LabVIEW does not 'normally' run as a console application. So, making it write to StdOut and StdErr is not simple. But, it can be done with some hacking (in Windows). Not sure if it is possible in OSX or Linux.

But, keep in mind that you get one shot at sending in commands. The app must then process those commands, write to the StdOut and then exit. You cannot send additional commands via the CMD console. (search LAVA for a thread on this from last year)

If you need continuous commands to a running application, I would suggest you write a DLL or create a web service interface for your application. The bonus of the web service is you can use something like curl on the CMD line to send and receive data and you can do that from any machine on the network.

good luck!

-John

Link to post
Share on other sites

No I need to run an Mercurial API command, and read it's output.

Sometimes I have to do this many times due to some issues out of my control, I have a hunch that opening the CMD is quite extensive. So I want to remove that overhead.

Ton

Link to post
Share on other sites

The multiple calls isn't an issue - that's the fundamental reason batch files exist. I was trying to get at the fact that you might be able to move some of your logic from LabVIEW into the batch file, eliminating the need for multiple call-and-returns. If that still isn't making sense, post a flowchart of your process and I'll see if it'll work in MS Batch.

Link to post
Share on other sites
It's not the looping I'm concerned about, it's more that I've got a lot of calls, that I need to route via an executable. Ton

Ton,

How about using the following process, for controlling any third-party executable running on cmd prompt using WinAPIs:

1) Get the third party window handle by using GetWindowHandle API.

2) Use AttachConsole() API from kernel32.dll - This would make the third party console controllable through LabVIEW

3) Use GetConsoleScreenBufferInfo() from kernel32.dll, with which you can read the console information

4) Use another function (can't remember the function name) which would write to the console

5) Repeat Step 3 and read the output for the written command in step 4 (you might need to do some string parsing to get the desired output)

6) Use FreeConsole() function from kernel32 again, to free up the console at the end of the application.

This way, you don't need to redevelop the third party app in labview, rather you could re-use the cmd prompt with this method with labview and have control/read data on it.

I am planning to make a small example of this and post it very soon.

-FraggerFox!

Edited by FraggerFox
  • Like 2
Link to post
Share on other sites

It's not the looping I'm concerned about, it's more that I've got a lot of calls, that I need to route via an executable.

Ton

You could save the cmd intermediate process creation altogether by directly piping into the (Mercurial) command line tool. And if you use the OpenG Pipe functions you could potentially even use the same single mercurial command line instance to issue many commands after each other through a pipe to the stdin and receive any response through another pipe from stdout.

And your hunch that process creation is quite an expensive task under Windows is quite right. And doing this through CMD really doubles that. But unless you need to also access Windows shell features, such as its build in commands, or locating an unqualified executable name in one of the PATH directories, it should be usually not a problem to directly instantiate the target command line app, by simply issuing its fully qualified exe name as first parameter, leaving out the cmd \c step completely.

Link to post
Share on other sites

... it should be usually not a problem to directly instantiate the target command line app, by simply issuing its fully qualified exe name as first parameter, leaving out the cmd \c step completely.

As an exception, I wanted to throw out that I had an instance some weeks ago with calling an external executable (a C-based Windows 32-bit executable written by me) with System Exec.vi which would always return LabVIEW's error 2 ("Memory is full"). The situation required a relatively quick fix, so I added in the cmd /c call and it worked. I'd like to go back any figure what's going on; the EXE itself is a mere 8KB and only depends on one atypical component (bthprops.cpl).

Link to post
Share on other sites
  • 4 months later...

You could save the cmd intermediate process creation altogether by directly piping into the (Mercurial) command line tool. And if you use the OpenG Pipe functions you could potentially even use the same single mercurial command line instance to issue many commands after each other through a pipe to the stdin and receive any response through another pipe from stdout.

I detected that Mercurial has a commandserver/pipe interface, after some debugging I got a stable 38 msec per call for the most basic call, (coming from 150 msec) so that speed improvement is pretty good.

Here's the code I ended with:

post-2399-0-58480300-1334304017_thumb.pn

Do you know what the overhead per dll call is?

Ton

  • Like 1
Link to post
Share on other sites

I detected that Mercurial has a commandserver/pipe interface, after some debugging I got a stable 38 msec per call for the most basic call, (coming from 150 msec) so that speed improvement is pretty good.

Here's the code I ended with:

post-2399-0-58480300-1334304017_thumb.pn

Do you know what the overhead per dll call is?

Ton

Well DLL call overhead is in the order of microsoeconds or less. You could experiment with the configuration of the Call Library Node and change the error reporting mode (in the extreme case to Disabled), but I doubt you would see any significant difference there.

The delay is most likely in passing the command over the pipe itself and then even more in the interpretation and execution of the command in the program.

And your two String Subset Functions could be replaced by a single Split String node.

Link to post
Share on other sites
  • 1 year later...

Ton,

How about using the following process, for controlling any third-party executable running on cmd prompt using WinAPIs:

1) Get the third party window handle by using GetWindowHandle API.

2) Use AttachConsole() API from kernel32.dll - This would make the third party console controllable through LabVIEW

3) Use GetConsoleScreenBufferInfo() from kernel32.dll, with which you can read the console information

4) Use another function (can't remember the function name) which would write to the console

5) Repeat Step 3 and read the output for the written command in step 4 (you might need to do some string parsing to get the desired output)

6) Use FreeConsole() function from kernel32 again, to free up the console at the end of the application.

This way, you don't need to redevelop the third party app in labview, rather you could re-use the cmd prompt with this method with labview and have control/read data on it.

I am planning to make a small example of this and post it very soon.

-FraggerFox!

FraggerFox,

I'm very interested in your solution. Did you ever make an example (I'm using LV 8.6)?

Corey

Link to post
Share on other sites
  • 1 year later...

If anyone stumbles across this, a better method is to use the windows .net calls.

 

https://msdn.microsoft.com/en-us/library/system.diagnostics.process%28v=vs.110%29.aspx

 

its probably the same thing system exec does under the hood, but you get asynchronous control of standard in, out, and err.

 

I'm certain the performance of this will crush anything else, and all the software is already on your windows machine.  

 

~Jon

Edited by Jon Kokott
  • Like 2
Link to post
Share on other sites
  • 1 year later...

Ton,

How about using the following process, for controlling any third-party executable running on cmd prompt using WinAPIs:

1) Get the third party window handle by using GetWindowHandle API.

2) Use AttachConsole() API from kernel32.dll - This would make the third party console controllable through LabVIEW

3) Use GetConsoleScreenBufferInfo() from kernel32.dll, with which you can read the console information

4) Use another function (can't remember the function name) which would write to the console

5) Repeat Step 3 and read the output for the written command in step 4 (you might need to do some string parsing to get the desired output)

6) Use FreeConsole() function from kernel32 again, to free up the console at the end of the application.

This way, you don't need to redevelop the third party app in labview, rather you could re-use the cmd prompt with this method with labview and have control/read data on it.

I am planning to make a small example of this and post it very soon.

-FraggerFox!

 

FraggerFox,

Did you make any example for this. If yes, it will be great if you share it.

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.