tags:

views:

50

answers:

2

Hi to all.

I've made a simple Lua-execution in Ada, it cooly run everything I need via Lua.Load_Buffer("os.execute('wxlua.exe wx.lua')") but I don't need win32 cmd.exe-window, which is default opens on program's start-up. Is there any way to control this event directly from Ada?

P.S. os.execute() sends commands directly to Windows, not via cmd.exe.

+2  A: 

To help see what's going on, try creating a desktop shortcut that executes that command.

If double-clicking on it also brings up the win32 cmd.exe window, then that means they compiled wxlua.exe to be a windows console app. You can try reading their docs or poking around in their exe directory to see if there's a Win32 version instead. If that doesn't do it for you, your best remaining option I know of is to call Win32's CreateProcess with the CREATE_NO_WINDOW or DETACHED_PROCESS flag set instead of using os.execute.

If the shortcut doesn't bring up a console window, that means os.execute is doing it to you. In that case, you'll have to go directly to the CreateProcess solution mentioned above.

Gnat should come with the Win32 bindings you need to call CreateProcess. If you'd like a cleaner interface to that routine, I have some thicker bindings I created to some of the Win32 calls, including that one and some other calls associated with creating Win32 services. I released them to the Public Domain (or tried to...) They are available in the source distribution of my old SETI@Home Service, and I believe they are somewhere in the examples directory of AWS (at least it used to be before ACT took it over).

T.E.D.
Archinamon
@Archinamon - I haven't used it myself, but the gnavi stuff still seems to be at least semi-actively developed, so it probably should have been on my reccomended list.
T.E.D.
+2  A: 

Standard Lua os.execute calls the standard C function system(). The C standard only requires that system() do something platform dependent, and specifically avoids saying what that might be. On Unix-like platforms, system() usually invokes the shell /bin/sh. On Windows it usually invokes cmd.exe.

Of course, its exact implementation could depend on exactly which toolchain you are using. You haven't said where you got your Lua (or for that matter, who's Ada compiler you have). One likely and recommended source is Lua for Windows, which is linked to the C runtime library from VC8, aka VS2005. Quoting from VS2005's documentation:

int system(const char *command);

.... The system function passes command to the command interpreter, which executes the string as an operating-system command. system refers to the COMSPEC and PATH environment variables that locate the command-interpreter file (the file named CMD.EXE in Windows NT and later). If command is NULL, the function simply checks to see whether the command interpreter exists.

Since os.execute calls system which invokes cmd.exe, you will get the console window. The way to avoid that is to not use os.execute.

If the program being executed is compiled for Windows Console Mode, then you will get a console window, regardless. However, wxlua.exe is almost certainly not compiled as a console application since it is intended to host GUI applications written in Lua based on the wxWidgets library.

Edit: Naturally, if your lua.exe is built in a way that replaces either the implementation of os.execute or the standard library routine system() with a different implementation then you might see different results.

To demonstrate that standard Lua's os.execute() eventually invokes cmd.exe, try the following:

C:\Documents and Settings\Ross>lua -e "os.execute[[pause]]"
Press any key to continue . . .

C:\Documents and Settings\Ross>wlua -e "os.execute[[pause]]"

C:\Documents and Settings\Ross>

This invokes a simple Lua script from the standard Lua interpreter, first the usual one that is a console application, and second from the variation supplied with Lua for Windows who's only difference is that it is linked to be a Windows GUI application.

Both cause the "Press any key" message to appear. The first in the same console window where I invoked Lua, and the second in a separate console.

Before hitting a key, I used PsList from Sysinternals in a separate console to show the process tree, with the command pslist -t. I've excerpted out only the relevant bits below:

C:\Documents and Settings\Ross>pslist -t

pslist v1.29 - Sysinternals PsList
Copyright (C) 2000-2009 Mark Russinovich
Sysinternals

Process information for LAMPWORK:

Name                             Pid Pri Thd  Hnd      VM      WS    Priv
Idle                               0   0   2    0       0      16       0
  System                           4   8  79 1208    1884     220       0
  ...
explorer                        3592   8  17 1263  115968   33964   25816
  ...
  cmd                           4300   8   1   96   35032    4448    2260
    PsList                      4688  13   2  109   29556    2776    1248
  cmd                           5208   8   1   33   30340    2704    1984
    lua                         5592   8   1   17    8528    1564     400
      cmd                       5680   8   1   30   30144    2428    1956

Notice that the instance of CMD that invoked Lua has a CMD as a child.

Repeating the experiment with wlua -e "os.execute[[pause]]" and pslist -t again:

C:\Documents and Settings\Ross>pslist -t
....
Name                             Pid Pri Thd  Hnd      VM      WS    Priv
Idle                               0   0   2    0       0      16       0
  ...
explorer                        3592   8  16 1251  115712   33956   25752
  ...
  cmd                           4300   8   1   96   35032    4448    2260
    PsList                      4888  13   2  109   29556    2780    1248
  procexp                       4800  13   7  328  108492   33232   29464
  cmd                           5208   8   1   32   30340    2704    1984
    wlua                        3272   8   1   15    8536    1576     400
      cmd                       5104   8   1   30   30144    2440    1956

Again, wlua has a CMD as a child.

Using ProcessExplorer, also from Sysinternals, I can see the command line of the child CMD process. It is CMD.EXE /C pause. In effect, system() prepends CMD /C to its argument and passes the result to spawn() for execution in a child process.

RBerteig
Well, os.execute even in standart Lua doesn't invoke cmd.exe as I quoted during tests. My Ada application always invokes cmd.exe, even I don't use LuaAda at all. I have GNAT 2010 (4.4.1) Programming Studio, where I compile all my projects, and LuaAda binding for latest Lua 5.1.4. Unfortunately i didn't found wxWindgets for Ada, so I used os.execute for launching my scripts under wxlua.exe.
Archinamon
@Archinamon, I've added some examples to my answer to explain my claim that `CMD` is invoked by `os.execute`. I don't speak Ada at all, and have no experience with LuaAda either. If you can find a way to spawn a child process from Ada without calling the C runtime's `system()` then that will be the right answer.
RBerteig