Выход из консольного приложения

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Jack Ferre
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 132
Зарегистрирован: 17.02.2014 (Пн) 14:31
Откуда: Казахстан, Костанай

Выход из консольного приложения

Сообщение Jack Ferre » 21.04.2015 (Вт) 8:32

Как корректно завершить выполнение консольного приложения?

При закрытии окошка или нажатия Ctrl+C в консоли убивается процесс. Можно как-то отловить выход?

Т.к. решения пока нет, решил сделать выход по вводу команды:
Код: Выделить всё
Do
    If stdin.ReadLine = "q" Then
        ' Здесь завершение программы
        Exit Do
    End If
Loop

И всё вроде бы прекрасно, да вот только программа не выполняется - заблокирована. А заводить поток под ReadLine чёт не хочется.

P.S. Спасибо за EasyConsole

Jack Ferre
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 132
Зарегистрирован: 17.02.2014 (Пн) 14:31
Откуда: Казахстан, Костанай

Re: Выход из консольного приложения

Сообщение Jack Ferre » 21.04.2015 (Вт) 10:20

Извиняюсь. Нарушил одну из заповедей.

Нашел SetConsoleCtrlHandler. Изловить событие выхода получилось. Однако при завершении программа падает, хотя в коде всё в порядке.
MSDN писал(а):Because the system creates a new thread in the process to execute the handler function, it is possible that the handler function will be terminated by another thread in the process. Be sure to synchronize threads in the process with the thread for the handler function.

Следовало сразу догадаться - не из воздуха же callback вызывается.

Итого уже 2 причины возиться с потоками. Т.к. парой строчек кода тут не обойтись (в текущем проекте стараюсь писать минимум лишнего) и в данном случае завершение процесса не критично, придется забить :cry:

Хакер
Телепат
Телепат
Аватара пользователя
 
Сообщения: 16478
Зарегистрирован: 13.11.2005 (Вс) 2:43
Откуда: Казахстан, Петропавловск

Re: Выход из консольного приложения

Сообщение Хакер » 21.04.2015 (Вт) 11:06

Jack Ferre писал(а):Итого уже 2 причины возиться с потоками. Т.к. парой строчек кода тут не обойтись

Наоборот, напиши предельно легковесный хендлер.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Jack Ferre
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 132
Зарегистрирован: 17.02.2014 (Пн) 14:31
Откуда: Казахстан, Костанай

Re: Выход из консольного приложения

Сообщение Jack Ferre » 21.04.2015 (Вт) 20:07

Написал рабочий вариант. Выпилил процентов 70 кода, чтобы получился
Хакер писал(а):предельно легковесный хендлер


Код: Выделить всё
Private lpOldProc As Long
Private hwndConsole As Long
Private tidConsoleHandler As Long

Public Sub Con_Init(ByVal hwnd As Long)
    hwndConsole = hwnd
    lpOldProc = SetWindowLong(hwndConsole, GWL_WNDPROC, AddressOf WNDPROC_Console)
    Call SetConsoleCtrlHandler(AddressOf CALLBACK_ConsoleHandler, True)
End Sub

Private Function WNDPROC_Console(ByVal hwnd As Long, ByVal msg As Long, ByVal wParam As Long, ByVal lParam As Long) As Long
    Select Case msg
        Case WM_CONQUIT
            AppStop     ' Событие завершения программы
           
            Call SetWindowLong(hwndConsole, GWL_WNDPROC, lpOldProc)
            PostThreadMessage tidConsoleHandler, WM_CONQUIT, 0, 0
        Case Else
            CallWindowProc lpOldProc, hwnd, msg, wParam, lParam
    End Select
End Function

Private Function CALLBACK_ConsoleHandler(ByVal lCtrlType As Long) As Boolean
    Dim msg As msg
   
    PostMessage hwndConsole, WM_CONQUIT, 0, 0
    tidConsoleHandler = GetCurrentThreadId
    Call GetMessage(msg, 0, 0, 0)
End Function


Хотел использовать окошко GetConsoleWindow для отлова сообщений, но какое-то оно негодное. Так что нужно своё.


Вернуться в Visual Basic 1–6

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 42

    TopList