我在Ada中做了一个简单的Lua执行,它通过Lua.Load_Buffer("os.execute('wxlua.exe wx.lua')")
运行我需要的所有内容,但是我不需要win32 cmd.exe-window,默认情况下会在程序的启动时打开。有没有办法直接从Ada控制这个事件?
P.S。 os.execute()直接将命令发送到Windows,而不是通过cmd.exe。
答案 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
是指COMSPEC
和PATH
定位的环境变量 命令解释器文件(文件 在Windows NT和Windows中命名为CMD.EXE
后来)。如果command
是NULL
,那么。{ 功能只是检查是否 命令解释器存在。
由于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
以便在子进程中执行。