Jump to content


Photo
* * * * * 1 votes

Running a LabVIEW EXE from the Console


  • Please log in to reply
30 replies to this topic

#1 John Lokanis

John Lokanis

    The 500 club

  • Premium Member
  • 577 posts
  • Location:Seattle, WA
  • Version:LabVIEW 2012
  • Since:1993

Posted 08 January 2010 - 02:23 AM

Ok, so this is a strange application, but I need to build a little exe that can be called from any scripting language (in this case Python) and can accept command line arguments and write its output to StdOut. So far, I have accomplished all this using the standard LV properties for getting the command line args and using some kernel32.dll calls to write to the StdOut of the cmd.exe console window.
Where this breaks down is when calling a LabVIEW exe from the console, the console thread is not blocked while the exe runs. So, the result is the console returns back the command prompt and then a little while later my exe sends the data to the console and it just appears where ever the cursor is currently at. :(
So, I need to figure out a way for my exe to steal the thread of the console and block it until it is done writting its output.

Any gurus out there have a idea even where to start figuring this one out? It has me baffled. :frusty:

BTW: if you also have a .NET solution for writing to the stdout instead of the old school kernel32.dll solution, I would love to see it.

thanks for the help and/or sympathy.

-John

PS. If you are wondering why the *$@#$! anyone would want to do this, basically it comes down to the need for some non-LabVIEW DEVs to control some cFP hardware over Ethernet and the only way I know how to do this is using LOGOS via DataSockets and that only works in LabVIEW!
----------------------------------
John Lokanis
CLA
Twitter: @jlokanis

#2 hooovahh

hooovahh

    The 500 club

  • Members
  • PipPipPipPipPip
  • 776 posts
  • Version:LabVIEW 2011
  • Since:2004

Posted 08 January 2010 - 01:33 PM

I don't have any thing to add since I've never been able to accomplish what you are asking for. I've also wanted to write a command-line LabVIEW program from time to time and I've always had difficulty with the StdOut as well. Sounds like you were able to get farther than I ever did. I always ended up outputting to a new command line window instead of the one it was ran in. If you don't mind could you post the code that you've got so far?

"Maybe Hoovah is really Crelf's alter-ego, which he uses to irk people?" - Gary Rubin

"Seemingly minor changes....can mean the difference between a working app and a quivering heap of unresponsive code." - David Boyd


#3 asbo

asbo

    I have no idea what you're talking about... so:

  • V I Engineering, Inc.
  • 1,273 posts
  • Version:LabVIEW 2011
  • Since:2008

Posted 08 January 2010 - 03:44 PM

Is there any reason you can't call the LV app using something like "start /wait $exe"? start is a Windows-specific utility, but I'm sure other platforms (if you need them) have something similar.

#4 John Lokanis

John Lokanis

    The 500 club

  • Premium Member
  • 577 posts
  • Location:Seattle, WA
  • Version:LabVIEW 2012
  • Since:1993

Posted 08 January 2010 - 08:13 PM

Sweet! That solves it. So, now we can write a LabVIEW console app!

Here is the VI that let's you write to the StdOut of the calling console:

Attached File  Write to StdOut of Calling Parent.vi   10.92K   892 downloads

-John
----------------------------------
John Lokanis
CLA
Twitter: @jlokanis

#5 smenjoulet

smenjoulet

    Very Active

  • Premium Member
  • 125 posts
  • Location:Dallas, TX
  • Version:LabVIEW 2010
  • Since:1992

Posted 08 January 2010 - 08:28 PM

BTW: if you also have a .NET solution for writing to the stdout instead of the old school kernel32.dll solution, I would love to see it.


As far as .NET goes, you can use System.Console to control your console window (write, write line, position cursor, etc.) but unfortunately I think you still need one API call to kernal32.dll for either AllocConsole() or AttachConsole() before any .NET calls.

You can then either use asbo's solution using start or use the props/methods of System.Console to position the cursor and "erase" part of the screen before writing your text if you're just wanting to make it look nice. The latter is a little hacky.

If there is a pure .NET solution, I haven't found it, so if you figure it out let us know.

Incidentally, in Linux I always just used the 'Write to Text File' function with a path of dev/stdout and it worked great.

-Scott
Simple <> Easy. Just because it may be simple, does not mean it is easy!

#6 hooovahh

hooovahh

    The 500 club

  • Members
  • PipPipPipPipPip
  • 776 posts
  • Version:LabVIEW 2011
  • Since:2004

Posted 08 January 2010 - 08:33 PM

Incidentally, in Linux I always just used the 'Write to Text File' function with a path of dev/stdout and it worked great.

-Scott

I did not know Linux had that feature, a pretty handy one. It would be nice if Windows came with such a feature.

"Maybe Hoovah is really Crelf's alter-ego, which he uses to irk people?" - Gary Rubin

"Seemingly minor changes....can mean the difference between a working app and a quivering heap of unresponsive code." - David Boyd


#7 asbo

asbo

    I have no idea what you're talking about... so:

  • V I Engineering, Inc.
  • 1,273 posts
  • Version:LabVIEW 2011
  • Since:2008

Posted 08 January 2010 - 08:36 PM

Sweet! That solves it. So, now we can write a LabVIEW console app!

Here is the VI that let's you write to the StdOut of the calling console:

Awesome! Do you have any code that will create a console window for output if there isn't a parent? Certainly would be handy for development.

#8 John Lokanis

John Lokanis

    The 500 club

  • Premium Member
  • 577 posts
  • Location:Seattle, WA
  • Version:LabVIEW 2012
  • Since:1993

Posted 08 January 2010 - 08:40 PM

Awesome! Do you have any code that will create a console window for output if there isn't a parent? Certainly would be handy for development.


Just replace the AttachConsole with the AllocConsole and drop the input arg.
----------------------------------
John Lokanis
CLA
Twitter: @jlokanis

#9 asbo

asbo

    I have no idea what you're talking about... so:

  • V I Engineering, Inc.
  • 1,273 posts
  • Version:LabVIEW 2011
  • Since:2008

Posted 08 January 2010 - 09:17 PM

Just replace the AttachConsole with the AllocConsole and drop the input arg.

Very cool. Thanks! :thumbup1:

Edit: Props go to hooovahh for this link, it messes with a few other things related to the console window.

Edited by asbo, 08 January 2010 - 09:20 PM.


#10 John Lokanis

John Lokanis

    The 500 club

  • Premium Member
  • 577 posts
  • Location:Seattle, WA
  • Version:LabVIEW 2012
  • Since:1993

Posted 08 January 2010 - 09:20 PM

No problem. It only took me 5 hours of googling the interwebs to sort that out. I wish there was a better way to learn how to use things like kernel32 and .NET functions...
----------------------------------
John Lokanis
CLA
Twitter: @jlokanis

#11 Jim Kring

Jim Kring

    packages everywhere!

  • JKI
  • 1,901 posts
  • Location:Lafayette, CA
  • Version:LabVIEW 2011
  • Since:1995

Posted 09 January 2010 - 04:09 AM

I tried to call this VI (built into an EXE) using System Exec from LabVIEW. The output does not show up in the STDOUT of the System Exec. It seems this only works when there is a console window (which is nice, but doesn't allow the EXE to be called from other applications in a way that lets them read the STDOUT). Did I miss anything?

#12 smenjoulet

smenjoulet

    Very Active

  • Premium Member
  • 125 posts
  • Location:Dallas, TX
  • Version:LabVIEW 2010
  • Since:1992

Posted 11 January 2010 - 04:34 PM

I tried to call this VI (built into an EXE) using System Exec from LabVIEW. The output does not show up in the STDOUT of the System Exec. It seems this only works when there is a console window (which is nice, but doesn't allow the EXE to be called from other applications in a way that lets them read the STDOUT). Did I miss anything?


Interesting. I haven't looked into it any further but if you use the .NET methods, it does work with System Exec. I've attached an example (LV20009) which allows writing with both kernel32 dll calls and .NET. The writes using the dll will not appear in STDOUT as you found, but the writes using .NET will.

Also, neither method as used works with redirection or piping, but it might be possible to get that to work as well if someone wanted to investigate it.

IIRC, The method in Linux of writing directly to dev/stdout with the file functions does support redirection at least (never tried piping).

-Scott

Attached Files


Simple <> Easy. Just because it may be simple, does not mean it is easy!

#13 John Lokanis

John Lokanis

    The 500 club

  • Premium Member
  • 577 posts
  • Location:Seattle, WA
  • Version:LabVIEW 2012
  • Since:1993

Posted 11 January 2010 - 08:11 PM

I tried to call this VI (built into an EXE) using System Exec from LabVIEW. The output does not show up in the STDOUT of the System Exec. It seems this only works when there is a console window (which is nice, but doesn't allow the EXE to be called from other applications in a way that lets them read the STDOUT). Did I miss anything?

Well, you got me stumped. I have tried allocating a console, tried geting the PID of the exe and then attaching to that console and tried not attaching to any console and I cannot get the LV System Exec call to work. :frusty:

This exhausts my knowledge of windows hacks to do something like this. I will leave it to others to sort this out. It's just another example of what a PITA windows programming is.... :throwpc:

-John

Interesting. I haven't looked into it any further but if you use the .NET methods, it does work with System Exec. I've attached an example (LV20009) which allows writing with both kernel32 dll calls and .NET. The writes using the dll will not appear in STDOUT as you found, but the writes using .NET will.

Also, neither method as used works with redirection or piping, but it might be possible to get that to work as well if someone wanted to investigate it.

IIRC, The method in Linux of writing directly to dev/stdout with the file functions does support redirection at least (never tried piping).

-Scott

I just tried your method using .NET to write the string. While this continued to work from the command line, I was unable to get this to work from the System Exec call. I can't seem to figure out what I am missing.
Any chance you know of a was to perform the AttachConsole within .NET? It would be nice to get rid of any DLL calls...
----------------------------------
John Lokanis
CLA
Twitter: @jlokanis

#14 John Lokanis

John Lokanis

    The 500 club

  • Premium Member
  • 577 posts
  • Location:Seattle, WA
  • Version:LabVIEW 2012
  • Since:1993

Posted 11 January 2010 - 08:27 PM

I just tried your method using .NET to write the string. While this continued to work from the command line, I was unable to get this to work from the System Exec call. I can't seem to figure out what I am missing.
Any chance you know of a was to perform the AttachConsole within .NET? It would be nice to get rid of any DLL calls...


I just tried building you exact code into an exe in LV2009 (instead of replicating the functions in 8.6.1 like I did above) and I still cannot get anything returned to the StdOut of the System Exec call from within LV. Are you sure you got that part to work?
Also, I think this might be related to the fact that the redirection and piping does not work.

-John
----------------------------------
John Lokanis
CLA
Twitter: @jlokanis

#15 smenjoulet

smenjoulet

    Very Active

  • Premium Member
  • 125 posts
  • Location:Dallas, TX
  • Version:LabVIEW 2010
  • Since:1992

Posted 11 January 2010 - 09:43 PM

Any chance you know of a was to perform the AttachConsole within .NET? It would be nice to get rid of any DLL calls...

No. If there is a pure .NET way, I haven't found it yet. I haven't searched real hard, so it may still be out there.

I just tried building you exact code into an exe in LV2009 (instead of replicating the functions in 8.6.1 like I did above) and I still cannot get anything returned to the StdOut of the System Exec call from within LV. Are you sure you got that part to work?

Positive. I just tried it again to be sure. I'm on XP. To be honest, I was a little surprised that it did work. More about that below.

Also, I think this might be related to the fact that the redirection and piping does not work.

I don't pretend to fully understand it yet, but my interpretation is that you're not really writing to stdout, but to the console which I think is a distinct but subtle difference. That is why I believe (at this point) that piping and redirection don't work, but also why I was surprised that the .NET WriteLine output appeared on stdout of System Exec (at least for me). There's a contradiction there, so more investigation of what is really happening is needed.

-Scott
Simple <> Easy. Just because it may be simple, does not mean it is easy!

#16 hooovahh

hooovahh

    The 500 club

  • Members
  • PipPipPipPipPip
  • 776 posts
  • Version:LabVIEW 2011
  • Since:2004

Posted 11 January 2010 - 10:13 PM

I don't pretend to fully understand it yet, but my interpretation is that you're not really writing to stdout, but to the console which I think is a distinct but subtle difference.

I would agree with you. The original problem remember was that the LV program would execute and then a few seconds later (when it was done) it would output to the command line. In the few seconds that the program ran the user could type stuff into the command line, and then the program would finish and append to what the user has already typed.

If an application is running I would think it would lock the command prompt from more user input unless it requested some. So the theory that the application is just doing a console write, instead of stdout may be correct.

"Maybe Hoovah is really Crelf's alter-ego, which he uses to irk people?" - Gary Rubin

"Seemingly minor changes....can mean the difference between a working app and a quivering heap of unresponsive code." - David Boyd


#17 John Lokanis

John Lokanis

    The 500 club

  • Premium Member
  • 577 posts
  • Location:Seattle, WA
  • Version:LabVIEW 2012
  • Since:1993

Posted 11 January 2010 - 10:23 PM

Positive. I just tried it again to be sure. I'm on XP. To be honest, I was a little surprised that it did work. More about that below.

I don't pretend to fully understand it yet, but my interpretation is that you're not really writing to stdout, but to the console which I think is a distinct but subtle difference. That is why I believe (at this point) that piping and redirection don't work, but also why I was surprised that the .NET WriteLine output appeared on stdout of System Exec (at least for me). There's a contradiction there, so more investigation of what is really happening is needed.


Can you post your exe? I have tried building an EXE from your VI in LV2009 and I cannot replicate what you are seeing with regards to the System Exec.

thanks,
-John

I would agree with you. The original problem remember was that the LV program would execute and then a few seconds later (when it was done) it would output to the command line. In the few seconds that the program ran the user could type stuff into the command line, and then the program would finish and append to what the user has already typed.

If an application is running I would think it would lock the command prompt from more user input unless it requested some. So the theory that the application is just doing a console write, instead of stdout may be correct.


Yes, the original issue was how to block the console while the app ran. And using the 'start /wait' command solved this. But, I think you are right about not really writing to StdOut. I wish I knew a Windows expert who I could ask...

-John
----------------------------------
John Lokanis
CLA
Twitter: @jlokanis

#18 smenjoulet

smenjoulet

    Very Active

  • Premium Member
  • 125 posts
  • Location:Dallas, TX
  • Version:LabVIEW 2010
  • Since:1992

Posted 11 January 2010 - 11:36 PM

Can you post your exe? I have tried building an EXE from your VI in LV2009 and I cannot replicate what you are seeing with regards to the System Exec.


Here it is. I've called it from System Exec in both 2009 and 8.6 and in both cases I get output in the 'standard output' indicator. If it still doesnt work for you, can you add any info about your setup.

-Scott

Attached Files


Simple <> Easy. Just because it may be simple, does not mean it is easy!

#19 Jim Kring

Jim Kring

    packages everywhere!

  • JKI
  • 1,901 posts
  • Location:Lafayette, CA
  • Version:LabVIEW 2011
  • Since:1995

Posted 11 January 2010 - 11:45 PM

Here it is. I've called it from System Exec in both 2009 and 8.6 and in both cases I get output in the 'standard output' indicator.



The .NET solution works great for me (I can call the EXE using System Exec in LV 2009 on Windows 7 64-bit, and I get the standard output returned to System Exec, just as expected). Sweet!

Thanks,

#20 John Lokanis

John Lokanis

    The 500 club

  • Premium Member
  • 577 posts
  • Location:Seattle, WA
  • Version:LabVIEW 2012
  • Since:1993

Posted 11 January 2010 - 11:48 PM

Here it is. I've called it from System Exec in both 2009 and 8.6 and in both cases I get output in the 'standard output' indicator. If it still doesnt work for you, can you add any info about your setup.

-Scott

No joy here. I cannot get anything back from the System Exec call. It does open a console window and I can see the output in the window as I press the write buttons but when I choose exit and close the app's window, nothing is returned to the calling LV VI. Do you have anything special in your exe's ini file?

The .NET solution works great for me (I can call the EXE using System Exec in LV 2009 on Windows 7 64-bit, and I get the standard output returned to System Exec, just as expected). Sweet!

Thanks,

Weird. I get nothing under XP when calling from either LV2009 or 8.6.1. Maybe this is an XP issue. Can you try this on an XP machine and confirm?
----------------------------------
John Lokanis
CLA
Twitter: @jlokanis