1

Тема: AHK: Корректное закрытие окна консоли

В Linux есть такая замечательная вещь, как закрытие консоли по Ctrl-D. Пытаюсь сделать нечто подобное под Win.

Что уже попробовал:

Просто напечатать в консоли exit, и нажать Enter


$^d::
   WinGetClass, class, A
   if (class = "ConsoleWindowClass")
      Send, exit{Enter}
   else
      Send, ^d
   return

У меня такой способ работает не корреткно, конфликтует с Punto Switcher'ом -  когда нажимаю Ctrl-D первый раз, Punto реагируте и пытается переключить раскладку на русскую, получается, что в консоли печатается не exit, а уxit (первая буква - русская "у"). Скриншот:
http://i42.fastpic.ru/thumb/2012/0709/ce/c4e5580b0295926cf37fd7d2a566f9ce.jpeg
Если два раза подряд нажат Ctrl-D, то всё нормально.

Можно конечно просто закрыть окно WinClose, но ведь в консоли может выполняться какое-либо приложение, и закрытие окна автоматически закроет и приложение.

Как можно отследить, выполняется ли что-нибудь в консоли, и если нет, то закрыть её? И ещё вопрос: какой лучше способ предпочесть, печатание exit или WinClose?

2

Re: AHK: Корректное закрытие окна консоли

burn пишет:

Как можно отследить, выполняется ли что-нибудь в консоли, и если нет, то закрыть её?

Можно так:

F10::
   WinGet, CMD_PID, PID, ahk_class ConsoleWindowClass
   if !CMD_PID
      return
 
   ChildProcess := ""
   for process in ComObjGet("winmgmts:").ExecQuery("Select * from Win32_Process")
      if (process.ParentProcessId = CMD_PID && ChildProcess := 1)
         break
 
   if ChildProcess
      MsgBox, Существуют дочерние процессы!
   else
      WinClose, ahk_class ConsoleWindowClass
   return

Информация:
Process, пятый пример в конце статьи и далее по ссылке в MSDN.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Корректное закрытие окна консоли

teadrinker пишет:

Можно так:

Нельзя . Если элементарно запустить калькулятор из консоли, то этот код не позволит её закрыть. И наоборот, если консоль будет юзать "левый" процесс, то консоль будет закрыта. Даже если запустить из консоли процесс, который будет использовать эту консоль, а потом из этого процесса запустить ещё один и убить первый, то родственная связь пропадёт и консоль будет убита.
Я думаю нужно плясать от GetConsoleProcessList. Если вернёт единицу- значит только мы эту консоль юзаем и можно смело её рубить. Если 3 или больше, то рубить нельзя. Если двое, то хрен его знает- в простейшем варианте просто рубим, в чуть более сложном смотрим кто второй владелец и если это "%windir%\system32\cmd.exe" или "%windir%\SysWOW64\cmd.exe", то только тогда рубим.

   WinGet, dwProcessId, PID, A ;окно консоли должно быть активно.
   bResult := DllCall("AttachConsole", "uint", dwProcessId, "int")
   if(!bResult)
   {
      msgbox не удалось подключиться к консоли
      return 
   }
   MaxProcessCount := 10
   VarSetCapacity(lpdwProcessList, MaxProcessCount*4)
   ProcCount := DllCall("GetConsoleProcessList", "ptr", &lpdwProcessList, "uint", MaxProcessCount, "uint")
   if(!ProcCount)
   {
      msgbox не удалось получить список процессов
      return 
   }
   msgbox % "Эту консоль использует " . ProcCount . "процессов."
   DllCall("FreeConsole", "int")

4

Re: AHK: Корректное закрытие окна консоли

Александр_ пишет:

Если элементарно запустить калькулятор из консоли, то этот код не позволит её закрыть.

Да, ты прав, я поспешил. Но всё же лучше писать полный код, т. к. что-то мне подсказывает, что коллега burn вряд ли сможет его составить.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder