如何从Ada代码控制win32中的cmd窗口?

时间:2010-10-23 00:58:56

标签: lua ada cmd

我在Ada中做了一个简单的Lua执行,它通过Lua.Load_Buffer("os.execute('wxlua.exe wx.lua')")运行我需要的所有内容,但是我不需要win32 cmd.exe-window,默认情况下会在程序的启动时打开。有没有办法直接从Ada控制这个事件?

P.S。 os.execute()直接将命令发送到Windows,而不是通过cmd.exe。

2 个答案:

答案 0 :(得分:2)

要查看正在发生的情况,请尝试创建执行该命令的桌面快捷方式。

如果双击它也会显示win32 cmd.exe窗口,那么这意味着他们将wxlua.exe编译为Windows控制台应用程序。您可以尝试阅读他们的文档或在他们的exe目录中浏览,看看是否有Win32版本。如果这不适合你,我知道的最好的剩余选项是使用CreateProcess设置而不是使用os.execute来调用Win32的CREATE_NO_WINDOW or DETACHED_PROCESS flag

如果快捷方式 没有显示控制台窗口,则表示os.execute正在对您进行操作。在这种情况下,您必须直接转到上面提到的CreateProcess解决方案。

Gnat应该带有你需要调用CreateProcess的Win32绑定。如果你想要一个更简洁的例程接口,我会为一些Win32调用创建一些更厚的绑定,包括与创建Win32服务相关的一个和其他一些调用。我将它们发布到公共域(或试图...)它们在我的旧SETI@Home Service的源代码发行版中可用,我相信它们位于AWS的示例目录中的某个位置(至少它曾经是在ACT接管之前完成的。)

答案 1 :(得分:2)

标准Lua os.execute调用标准C函数system()。 C标准只要求system()做一些与平台相关的事情,并特别避免说出可能是什么。在类Unix的平台上,system()通常会调用shell /bin/sh。在Windows上,它通常会调用cmd.exe

当然,它的确切实现可能取决于您使用的确切工具链。你还没有说过你在哪里得到你的Lua(或者就此而言,你有Ada编译器)。一个可能和推荐的源是Lua for Windows,它链接到VC8的C运行时库,又名VS2005。引自VS2005's documentation

  

int system(const char *command);

     

....系统函数将命令传递给   命令解释器,哪个   将字符串作为一个执行   操作系统命令。 system   是指COMSPECPATH   定位的环境变量   命令解释器文件(文件   在Windows NT和Windows中命名为CMD.EXE   后来)。如果commandNULL,那么。{   功能只是检查是否   命令解释器存在。

由于os.execute调用调用system的{​​{1}},您将获得控制台窗口。避免这种情况的方法是不使用cmd.exe

如果正在执行的程序是针对Windows控制台模式编译的,那么无论如何都会得到一个控制台窗口。但是,os.execute几乎肯定不会编译为控制台应用程序,因为它旨在托管基于wxWidgets库在Lua中编写的GUI应用程序。

修改 当然,如果您的lua.exe构建方式可以替换wxlua.exe的实现或标准库例程os.execute的实现,那么您可能会看到不同的结果。

要证明标准Lua的system()最终调用os.execute(),请尝试以下操作:

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>

这将调用标准Lua解释器中的简单Lua脚本,首先是通常的控制台应用程序,第二个是Lua for Windows提供的变体,唯一的区别是它链接为Windows GUI应用程序。

两者都会显示“按任意键”消息。第一个在我调用Lua的同一个控制台窗口中,第二个在一个单独的控制台中。

在点击密钥之前,我在单独的控制台中使用PsList from Sysinternals来显示进程树,并使用命令cmd.exe。我只摘录了下面的相关内容:

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

请注意,调用Lua的CMD实例将CMD作为子级。

再次使用pslist -t和pslist -t重复实验:

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

同样,wlua -e "os.execute[[pause]]"有一个CMD作为孩子。

使用来自Sysinternals的ProcessExplorer,我可以看到子wlua进程的命令行。它是CMD。实际上,CMD.EXE /C pause会将system()添加到其参数中,并将结果传递给CMD /C以便在子进程中执行。