Технические вопросы и ответы QA1134

Программно вызывающий перезапуск, завершение работы и/или выход из системы

Q: Как я программно завершаю работу, перезапустите, спите или выйдите из системы машина рабочий Mac OS X?

A: Как я программно завершаю работу, перезапустите, спите или выйдите из системы машина рабочий Mac OS X?

Приложение может сделать все вышеупомянутое путем отправки определенных событий Apple в процесс loginwindow. Процесс loginwindow интерпретирует события Apple и вызовет требуемое событие. Можно предназначаться для процесса loginwindow для событий Apple с помощью константы {0, kSystemProcess} как ProcessSerialNumber целевого приложения. Обратите внимание на то, что перезапуск, завершение работы или инициируемое использование последовательности выхода из системы этого метода могут быть отменены запущенными приложениями.

Для получения дополнительной информации на приложениях, отменяющих последовательность перезапуска/завершения работы/выхода из системы, см. «Процессы Завершения» в Системных Темах Программирования Запуска.

Определенные события Apple, отправленные для инициирования системного перезапуска, завершения работы, выхода из системы или сна, являются kAERestart, kAEShutDown, kAEReallyLogOut или kAESleep, соответственно.

Код ниже демонстрирует, как программно вызвать перезапуск, завершение работы, сон или выход из системы путем отправки событий Apple в процесс loginwindow. Функциональный SendAppleEventToSystemProcess выполняет работу отправки события Apple.

  Демонстрация перечисления 1 того, как программно перезапустить, завершите работу, спите и выйдите из системы система

#include <stdio.h> 
#include <CoreServices/CoreServices.h>
#include <Carbon/Carbon.h>

static OSStatus SendAppleEventToSystemProcess(AEEventID EventToSend);

int main(void)
{
    const int bufferSize = 256;
    OSStatus error = noErr;
    char select [bufferSize];

    printf("1: Restart computer\n");
    printf("2: Shutdown computer\n");
    printf("3: Logout computer\n");
    printf("4: Sleep computer\n");
    printf("q: quit program\n");

    printf("please enter choice:\n");fflush(stdout);
    fgets(select, bufferSize, stdin);

    switch (select[0])
    {
         case '1':
            //sending restart event to system
            error = SendAppleEventToSystemProcess(kAERestart);
            if (error == noErr)
                {printf("Computer is going to restart!\n");}
            else
                {printf("Computer wouldn't restart\n");}
         break;
         case '2':
            //sending shutdown event to system
            error = SendAppleEventToSystemProcess(kAEShutDown);
            if (error == noErr)
                {printf("Computer is going to shutdown!\n");}
            else
                {printf("Computer wouldn't shutdown\n");}
         break;
         case '3':
            //sending logout event to system
            error = SendAppleEventToSystemProcess(kAEReallyLogOut);
            if (error == noErr)
                {printf("Computer is going to logout!\n");}
            else
                {printf("Computer wouldn't logout");}
         break;
         case '4':
            //sending sleep event to system
            error = SendAppleEventToSystemProcess(kAESleep);
            if (error == noErr)
                {printf("Computer is going to sleep!\n");}
            else
                {printf("Computer wouldn't sleep");}
    };

    return(0);
}

OSStatus SendAppleEventToSystemProcess(AEEventID EventToSend)
{
    AEAddressDesc targetDesc;
    static const ProcessSerialNumber kPSNOfSystemProcess = { 0, kSystemProcess };
    AppleEvent eventReply = {typeNull, NULL};
    AppleEvent appleEventToSend = {typeNull, NULL};

    OSStatus error = noErr;

    error = AECreateDesc(typeProcessSerialNumber, &kPSNOfSystemProcess, 
                                            sizeof(kPSNOfSystemProcess), &targetDesc);

    if (error != noErr)
    {
        return(error);
    }

    error = AECreateAppleEvent(kCoreEventClass, EventToSend, &targetDesc, 
                   kAutoGenerateReturnID, kAnyTransactionID, &appleEventToSend);

    AEDisposeDesc(&targetDesc);
    if (error != noErr)
    {
        return(error);
    }

    error = AESend(&appleEventToSend, &eventReply, kAENoReply, 
                  kAENormalPriority, kAEDefaultTimeout, NULL, NULL);

    AEDisposeDesc(&appleEventToSend);
    if (error != noErr)
    {
        return(error);
    }

    AEDisposeDesc(&eventReply);

    return(error); 
}

Состояние электропитания изменяется от демонов

На Mac OS X демоны выполняются в глобальном контексте и без соединения с сервером окна. Поэтому они не должны, и часто не может, использовать метод, обрисованный в общих чертах выше для генерации изменений состояния электропитания.

Посмотрите Техническое примечание TN2083: Демоны и Агенты для получения дальнейшей информации о демонах и контекстах выполнения.

В случае, где нет никаких сеансов входа в систему GUI, демон может дать стандартную команду завершения работы для выключения системы, добавив»-r«отметьте, если желаем перезапуск. Демон может также спать система путем вызова IOPMSleepSystem.

Однако, если один или несколько сеансов входа в систему GUI активны, демон может использовать отдельный launchd агент в расчете на пользователя для реализации команд состояния электропитания события Apple, обрисованных в общих чертах выше. Межпроцессное взаимодействие между демонами и агентами обрисовано в общих чертах в Техническом примечании TN2083: Демоны и Агенты.



История версии документа


ДатаПримечания
24.09.2008

Обновленное исходное перечисление.

23.01.2008

Добавленная информация для авторов демона.

10.02.2003

Новый документ, описывающий, как программно вызвать перезапуск, завершение работы, сон или выход из системы.