Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Системное программирование и WinAPI > Событие выключения компьютора


Автор: lemax 7.1.2008, 14:43
Процесс находится в постоянном цикле с элементом Sleep(360000)
Код

for(;;)
{
...
sleep(sleepTime);
...
}


не дает выключить компьютор.
Помогите простым примерчиком решить эту проблему.

Может что-то такое http://forum.vingrad.ru/faq/topic-156310.html только на С++

Автор: JackYF 7.1.2008, 15:05
Цитата(lemax @  7.1.2008,  13:43 Найти цитируемый пост)
не дает выключить компьютор.

подробнее.

Автор: lemax 7.1.2008, 15:24
Цитата(JackYF @ 7.1.2008,  15:05)
Цитата(lemax @  7.1.2008,  13:43 Найти цитируемый пост)
не дает выключить компьютор.

подробнее.

Сообщение "Процесс такой-то не отвечает" (и варианты убить или не убить его). По истечении 15 сек ничего не происходит. Компьютор ждет, пока этот процесс не убьют  smile 

Автор: powerfox 7.1.2008, 15:29
Не знаю, как в винде, но, по идее, каждый процесс при выключении получает сигнал от операционной систему. Нужно его перехватить и выполнить break.

Автор: lemax 7.1.2008, 15:33
Цитата(powerfox @ 7.1.2008,  15:29)
Не знаю, как в винде, но, по идее, каждый процесс при выключении получает сигнал от операционной систему. Нужно его перехватить и выполнить break.

примерчик бы хотелось. Перехвата процессом без окна 

Автор: powerfox 7.1.2008, 15:50
Цитата(lemax @  7.1.2008,  16:33 Найти цитируемый пост)
примерчик бы хотелось. Перехвата процессом без окна  

В смысле? По идее, обычные С++ исключения. Наличие окна не влияет на получение сигнала. Просто надо знать, какие исключения ловить. Я с Windows API не знаком, но из того, что видел, вам нужно погуглить о исключениях завершения приложения.

Добавлено через 4 минуты и 50 секунд
Код

try{

for(;;)
{
...
sleep(sleepTime);
...
}

catch (Exception exception)
   {
   HandleException(exception);
   }

}


Как-то так, наверное. Ищите нужный тип исключения.

Автор: jonie 7.1.2008, 16:13
создайте окно и используйте его, например во втором потоке. Окно будет уведомлено, далее вы в первом потоке делаете например не цикл бесконечный, а цикл до Event-а... и вырубаетесь по нему...
пример в аттаче.
Цитата

По идее, обычные С++ исключения
неверно. ОС и С++ исключения не связаны (нуу если не говорить о "фишках" компляторов типа VC...)

ладно, признаю, мы тупые.
Код

#include <windows.h>

BOOL WINAPI EventHandler(DWORD event)
{
    switch(event)
    {
        case CTRL_C_EVENT:
        break;

        case CTRL_BREAK_EVENT:
        break;

        case CTRL_CLOSE_EVENT:
            // process any cleanup code and terminate
            return FALSE;
        break;

        case CTRL_LOGOFF_EVENT:
        break;

        case CTRL_SHUTDOWN_EVENT:
        break;
    }

    return TRUE;
}

void main()
{
    if (SetConsoleCtrlHandler(
    (PHANDLER_ROUTINE)EventHandler,TRUE)==FALSE)
    {
        return; // failed to install
    }

    while(1)
    {
    }

Автор: lemax 7.1.2008, 17:28
SetConsoleCtrlHandler

Приложение не консольное  smile 

Автор: jonie 7.1.2008, 19:47
так чем плох вариант создания окна ? пример я давал... ну скройте его и нет проблем имхо..
чтобы терминировала винда без показа окна можно воспользоваться SetProcessShutDownParameters
но я не считаю это верным подходом...

Автор: lemax 7.1.2008, 19:56
Цитата(jonie @ 7.1.2008,  19:47)
так чем плох вариант создания окна ? пример я давал... ну скройте его и нет проблем имхо..

Если бы я в этом разбирался я бы мигом это сделал. Но пока я вожусь с новой темой.
Если вдруг появится примерчик (процесс все события обрабатывает как DefWindowProc()) - буду только рад  smile

Автор: jonie 7.1.2008, 22:00
а что выше во вложении уже не пример оО ?

Автор: MAKCim 7.1.2008, 23:30
или я чего-то не понял
что, обычный процесс может заблокировать выключение системы?  smile 
я в шоке

Автор: JackYF 8.1.2008, 00:04
Цитата(MAKCim @  7.1.2008,  22:30 Найти цитируемый пост)
что, обычный процесс может заблокировать выключение системы?  smile 
я в шоке 

ну вообще-то я думал, что нет... система обычно убивает процесс через n секунд после того, как он перестаёт отвечать на запросы.

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

Автор: lemax 8.1.2008, 00:14
Цитата(jonie @ 7.1.2008,  22:00)
а что выше во вложении уже не пример оО ?

Семь бед - один ответ  smile http://www.ict.edu.ru/ft/004249/cpp_p4.pdf

Проблемку не решил. Но похоже это поможет.

jonie. Спасибо за примеры.

Добавлено через 10 минут и 38 секунд
Цитата(MAKCim @ 7.1.2008,  23:30)
или я чего-то не понял
что, обычный процесс может заблокировать выключение системы?  smile 
я в шоке

Я сам в шоке. Но баг из программы надо как-то убрать (сунули код- вот и парюсь).
А причина бага - это только догадки.

Автор: salexs 8.1.2008, 08:12
а если так....
include <stdio.h>
#include <windows.h>
#include <tlhelp32.h>
#include <vdmdbg.h>
#include <tchar.h>
#include <process.h> 
BOOL MySystemSleep()
{
  HANDLE hToken;
  TOKEN_PRIVILEGES tkp;

  BOOL fResult;

  if (!OpenProcessToken(GetCurrentProcess(),
       TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
     return FALSE;

  LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME,
       &tkp.Privileges[0].Luid);

  tkp.PrivilegeCount = 1;
  tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

  AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
     (PTOKEN_PRIVILEGES) NULL, 0);

  if (GetLastError() != ERROR_SUCCESS)
     return FALSE;

  fResult = SetSystemPowerState(FALSE,TRUE);

  if (!fResult)
     return FALSE;

  tkp.Privileges[0].Attributes = 0;
  AdjustTokenPrivileges(hToken, FALSE, &tkp, 0,
       (PTOKEN_PRIVILEGES) NULL, 0);

Автор: JackYF 8.1.2008, 11:14
salexs, пользуйся тегом "Код", пожалуйста.

Автор: lemax 8.1.2008, 11:15
Цитата(salexs @  8.1.2008,  08:12 Найти цитируемый пост)
а если так....
include <stdio.h>
#include <windows.h>


Ой, сколько нового для размышления  smile . Пороюсь, спосибо.

Я зашел сюда чтобы написать свой вариант и ,возможно, закрыть тему.


ДО:
Код

for(;;)
{
...
Sleep(3600);
...
}


ПОСЛЕ:
Код

MSG m_msg;
for(;;)
{
...
//======================
for(int i=lWaitingTime;i>=0;i-=3000 )
{
        Sleep(3000);
        while(PeekMessage(&m_msg, NULL, NULL, NULL, PM_REMOVE))
        {
            if(m_msg.message==WM_QUERYENDSESSION) exit (0);
        }
}
//=========================
...
}


Сообщите о замеченых проблемах этого жуткого подхода. 


Автор: jonie 9.1.2008, 09:11
я уже писал, вы прочитали или пропустили?smile
Цитата

чтобы терминировала винда без показа окна можно воспользоваться SetProcessShutDownParameters

в msdn посмотрите описание, думаю вам пойдет завалить процесс молча 8))

Автор: 0xDEAD 22.11.2009, 23:03
Возник аналогичный вопрос. Методы с SetConsoleCtrlHandler и с PeekMessage не работают. Есть еще альтернативы, кроме создания окна?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)