Как управлять cmd-окном в win32 из Ada-кода? - PullRequest
2 голосов
/ 23 октября 2010

Я сделал простое Lua-выполнение в Ada, оно здорово запускает все, что мне нужно, через Lua.Load_Buffer("os.execute('wxlua.exe wx.lua')"), но мне не нужно win32 cmd.exe-window, которое по умолчанию открывается при запуске программы.Есть ли способ контролировать это событие напрямую из Ada?

PS os.execute () отправляет команды непосредственно в Windows, а не через cmd.exe.

Ответы [ 2 ]

2 голосов
/ 25 октября 2010

Стандартный Lua os.execute вызывает стандартную функцию C system(). Стандарт C требует только, чтобы system() делал что-то зависящее от платформы, и, в частности, не говорил, что это может быть. На Unix-подобных платформах system() обычно вызывает оболочку /bin/sh. В Windows это обычно вызывает cmd.exe.

Конечно, его точная реализация может зависеть от того, какой именно набор инструментов вы используете. Вы не сказали, где вы получили свой Lua (или, между прочим, кто у вас есть компилятор Ada). Один вероятный и рекомендуемый источник - Lua для Windows , который связан с библиотекой времени выполнения C из VC8, также называемой VS2005. Цитирование из документации VS2005 :

int system(const char *command);

.... Системная функция передает команду командный интерпретатор, который выполняет строку как команда операционной системы. system относится к COMSPEC и PATH переменные среды, которые определяют местонахождение файл интерпретатора команд (файл с именем CMD.EXE в Windows NT и потом). Если command равно NULL, то Функция просто проверяет, интерпретатор команд существует.

Поскольку os.execute вызывает system, который вызывает cmd.exe, вы получите окно консоли. Чтобы избежать этого, не используйте os.execute.

Если выполняемая программа скомпилирована для режима консоли Windows, то вы получите окно консоли, независимо от этого. Однако wxlua.exe почти наверняка не скомпилировано как консольное приложение, поскольку оно предназначено для размещения приложений с графическим интерфейсом, написанных на Lua, на основе библиотеки wxWidgets .

Edit: Естественно, если ваш lua.exe построен таким образом, что заменяет реализацию os.execute или стандартную библиотечную подпрограмму system() другой реализацией, вы можете увидеть другие результаты.

Чтобы продемонстрировать, что стандартный Lua os.execute() в конечном итоге вызывает cmd.exe, попробуйте следующее:

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 для Windows, единственное отличие которого состоит в том, что он связан с приложением Windows GUI.

В обоих случаях появляется сообщение «Нажмите любую клавишу». Первый в том же окне консоли, где я вызывал Lua, а второй в отдельной консоли.

Перед нажатием клавиши я использовал PsList от Sysinternals в отдельной консоли, чтобы показать дерево процессов, с командой pslist -t. Я выделил только соответствующие биты ниже:

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

Обратите внимание, что экземпляр CMD, который вызвал Lua, имеет CMD в качестве дочернего элемента.

Повтор эксперимента с wlua -e "os.execute[[pause]]" и снова 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 имеет CMD в детстве.

Используя ProcessExplorer , также из Sysinternals, я вижу командную строку дочернего CMD процесса. Это CMD.EXE /C pause. По сути, system() добавляет CMD /C к своему аргументу и передает результат spawn() для выполнения в дочернем процессе.

2 голосов
/ 23 октября 2010

Чтобы увидеть, что происходит, попробуйте создать ярлык на рабочем столе, который выполняет эту команду.

Если двойной щелчок по нему также вызывает окно win32 cmd.exe, то это означает, что они скомпилировали wxlua.exeбыть приложением консоли Windows.Вы можете попробовать прочитать их документы или покопаться в их exe-каталоге, чтобы увидеть, есть ли версия для Win32.Если это вам не подходит, ваш лучший оставшийся вариант, о котором я знаю, это вызвать CreateProcess в Win32 с флагом CREATE_NO_WINDOW или DETACHED_PROCESS вместо использования os.execute.

Если ярлык не вызывает окно консоли, это означает, что os.execute делает это с вами.В этом случае вам придется перейти непосредственно к решению CreateProcess, указанному выше.

Gnat должен иметь привязки Win32, необходимые для вызова CreateProcess.Если вам нужен более понятный интерфейс для этой процедуры, у меня есть несколько более толстых привязок, которые я создал для некоторых вызовов Win32, включая этот и некоторые другие вызовы, связанные с созданием служб Win32.Я передал их в общественное достояние (или попытался ...). Они доступны в исходном дистрибутиве моего старого SETI @ Home Service , и я считаю, что они находятся где-то в каталоге примеров AWS (по крайней мере, так было до того, как его захватил ACT).

...