Как выключить компьютер из советника

Программирование прибыли: от азов к секретам мастерства. Читайте, спрашивайте, делитесь опытом.
Бонус за сообщение 0.5$
Ответственный Модератор - Haos

Как выключить компьютер из советника

Сообщение Kalkin » 16 мар 2016, 06:23

Для выключения компьютера в операционной системе семейства Windows есть специальная программа shutdown.exe. Находится она в папке \system32 каталога установки Windows. Всё, что требуется, чтобы из тела советника или скрипта выключить компьютер - это программно запустить её на исполнение.
Итак, что мы знаем о программе shutdown?
Команда SHUTDOWN используется для завершения сеанса пользователя, перезагрузки компьютера, перевода его в спящий режим или выключения питания. При наличии соответствующих разрешений, команда может выполняться для удаленной системы.
Формат командной строки:
SHUTDOWN.EXE [/i | /l | /s | /r | /g | /a | /p | /h | /e] [/f] [/m \\компьютер][/t xxx][/d [p|u]xx:yy [/c комментарий"]]
Если в командной строке не заданы параметры, или задан параметр /? - то на экран выдается краткая справка по использованию команды.
Вместо синтаксиса /ключ допускается использование -ключ:
SHUTDOWN.EXE [-i | -l | -s | -r | -g | -a | -p | -h | -e] [-f] [-m \\компьютер][-t xxx][-d [p|u]xx:yy [-c комментарий"]]
Параметры командной строки:
/i - Отображение графического интерфейса пользователя.
Этот параметр должен быть первым.
/l - Завершение сеанса. Этот параметр нельзя использовать с
параметрами /m или /d.
/s - Завершение работы компьютера.
/r - Завершение работы и перезагрузка компьютера.
/g Завершение работы и перезагрузка компьютера. После перезапуска
системы, запуск всех зарегистрированных приложений.
/a - Отмена завершения работы системы.
Этот параметр можно использовать только в период ожидания.
/p - Немедленное отключение локального компьютера без предупреждения.
Можно использовать с параметрами /d и /f.
/h - Переключение локального компьютера в режим гибернации.
Можно использовать с параметром /f.
/e - Указание причины непредвиденного завершения работы компьютера.
/o - Переход в меню дополнительных параметров загрузки и перезагрузка компьютера.
Данный параметр допустим для Windows 8 и более поздних версий. Необходимо использовать в с параметром /r.
/m \\компьютер - Имя или IP-адрес конечного компьютера.
/t xxx - Задание задержки в xxx секунд перед завершением работы
компьютера.
Допустимый диапазон: 0-315360000 (10 лет); значение по умолчанию: 30 секунд.
Если период таймаута больше 0, применяется
параметр /f.
/c "комментарий" - Комментарий с причиной перезапуска или завершения работы. Наибольшая длина - 512 знаков.
/f - Принудительное закрытие запущенных приложений без предупреждения пользователей.
Параметр /f используется, если для параметра /t
задано значение больше 0.
/d [p|u:]xx:yy Необходимо указать причину для перезагрузки или выключения.
"p" означает запланированную перезагрузку или завершение работы.
"u" означает, что причина определяется пользователем.
Если не задано ни "p", ни "u", перезагрузка или завершение работы
являются незапланированными.
xx является основным кодом причины (целое положительное число, меньшее 256).
yy является вспомогательным кодом причины (целое положительное число, меньшее 65536).

Для управления процессами выключения и перезагрузки, пользователь должен обладать правами администратора по отношению к управляемой системе.
Примеры использования команды SHUTDOWN:
shutdown или shutdown /? - отобразить справку по использованию команды.
shutdown /s - выключить питание компьютера через 30 секунд. Пользователю будет выдано предупреждение о запланированном выключении.
shutdown /s /t 0 - выключить питание компьютера немедленно.



Для нашей задачи необходимо просто отключить компьютер без задержки времени, поэтому формат команды должен быть таким:
Код: выделить все
shutdown /s /t 0

А если подойти к вопросу более жестко, наплевав на все другие программы для ускорения выключения, то и так:
Код: выделить все
shutdown /s /f


Какими средствами из арсенала MQL4 можно заставить выполняться внешнюю программу? Смотрим далее.
Аватар пользователя
Kalkin
 
Сообщений: 1589
Зарегистрирован: 05 мар 2015, 06:51
Средств на руках: 108.80 Доллар
Награды: 2
Ветеран I (1) Медаль за научный вклад (1)
Группа: Базовая
Благодарил (а): 633 раз.
Поблагодарили: 1190 раз.
Ace Register Votive

Как выключить компьютер из советника

Сообщение Kalkin » 16 мар 2016, 06:39

Один из наиболее простых вариантов для запуска заданной прикладной программы - воспользоваться функцией WinExec из состава библиотеки kernel32.dll. Тем более, что эта функция предусмотрена для совместимости с более ранними версиями Windows, так что должна работать везде.
Синтаксис:
Код: выделить все
UINT WinExec(
      LPCSTR lpCmdLine, // адрес командной линии
      UINT uCmdShow     // стиль окна
);

Параметры:
lpCmdLine Указывает на строку символов с нулем в конце, которая содержит командную линию (имя файла плюс необязательные параметры) для прикладной программы, которая будет исполняться.
uCmdShow Флаги функции,определяющие вид окна после запуска:
SW_HIDE = 0
Скрыть окно и активизировать другое окно.
SW_MAXIMIZE = 3
Развернуть окно.
SW_MINIMIZE = 6
Свернуть окно и активизировать следующее окно в Z-порядке(следующее под свернутым окном).
SW_RESTORE = 9
Активизировать и отобразить окно.Если окно свернуто или развернуто,Windows восстанавливает его исходный размер и положение.
SW_SHOW = 5
Активизировать окно.
SW_SHOWMAXIMIZED = 3
Отобразить окно в развернутом виде.
SW_SHOWMINIMIZED = 2
Отобразить окно в свернутом виде.
SW_SHOWMINNOACTIVE = 7
Отобразить окно в свернутом виде.Активное окно остается активным.
SW_SHOWNA = 8
Отобразить окно в текущем состоянии.Активное окно остается активным.
SW_SHOWNOACTIVATE = 4
Отобразить окно в соответствии с последними значениями позиции и размера.Активное окно остается активным.
SW_SHOWNORMAL = 1
Активизировать и отобразить окно.Если окно свернуто или развернуто,Windows восстанавливает его исходный размер и положение.Приложение должно указывать этот флаг при первом отображении окна.



Итак, мы должны воспользоваться функцией WinExec, в первый параметр которой передать имя исполняемой программы с параметрами, в нашем случае shutdown /s /t 0, а во второй параметр - вид окна: SW_HIDE.
Задачи уяснены, приступаем собственно к кодированию.
Аватар пользователя
Kalkin
 
Сообщений: 1589
Зарегистрирован: 05 мар 2015, 06:51
Средств на руках: 108.80 Доллар
Награды: 2
Ветеран I (1) Медаль за научный вклад (1)
Группа: Базовая
Благодарил (а): 633 раз.
Поблагодарили: 1190 раз.
Ace Register Votive

Как выключить компьютер из советника

Сообщение Kalkin » 16 мар 2016, 07:07

Прежде всего напоминаю, что начиная с билда 600 язык программирования MQL4 претерпел существенные изменения, что отразилось на способе передачи строковых параметров в функции динамически загружаемых библиотек. Строки теперь представлены в формате Unicode, раньше они были в формате ANSI (однобайтовые).

Для старого билда достаточно было указать строковую переменную типа string для DLL:

Код: выделить все
#import "kernel32.dll"
int WinExec(string lpCmdLine,int uCmdShow);

и в коде советника выполнить оператор:
Код: выделить все
WinExec("shutdown /t 0 /s",0);


Однако, на данный момент такой код просто не будет работать, а сама функция вернет код ошибки ERROR_FILE_NOT_FOUND, а это будет означать то, что функция не получила имя исполняемой программы в должном виде.

Для того, чтобы правильно передать строковые параметры функции из состава DLL, необходимо объявить их как ссылку на символьный массив и именно такой массив передавать функции. Объявление для функции WinExec будет выглядеть так:
Код: выделить все
#import "kernel32.dll"
int WinExec(uchar &lpCmdLine[],uint uCmdShow);

А чтобы подготовить данные для передачи в функцию, надо выполнить некоторое количество преобразований:
Код: выделить все
      uchar ucParam[];                           // определяем строковый массив
      string sParam = "shutdown /t 0 /s";        // подготавливаем текст для первого параметра
      ArrayResize(ucParam, StringLen(sParam)+1); // резервируем память для строкового массива
      StringToCharArray(sParam, ucParam);        // переносим текст в строковый массив

И, наконец-то, вызываем функцию, запускающую на исполнение программу выключения компьютера:
Код: выделить все
      int result = WinExec(ucParam,0);     // завершить работу компьютера
Аватар пользователя
Kalkin
 
Сообщений: 1589
Зарегистрирован: 05 мар 2015, 06:51
Средств на руках: 108.80 Доллар
Награды: 2
Ветеран I (1) Медаль за научный вклад (1)
Группа: Базовая
Благодарил (а): 633 раз.
Поблагодарили: 1190 раз.
Ace Register Votive

Как выключить компьютер из советника

Сообщение Kalkin » 16 мар 2016, 07:33

Пример использования.
Ожидается, что советник завершит сопровождение позиций, и когда они все закроются, необходимо выключить компьютер. Например, это может произойти ночью. Для выполнения задачи предлагаю воспользоваться скриптом, который будет ожидать до тех пор, когда не будет открытых позиций и отложенных ордеров, после чего закроет терминал и выключит компьютер:
Код: выделить все
//+------------------------------------------------------------------+
//|                                                  KS_ShutDown.mq4 |
//|                                       Kalkin, www.investforum.ru |
//|                                        http://www.investforum.ru |
//+------------------------------------------------------------------+
#property copyright "Kalkin, www.investforum.ru"
#property link      "http://www.investforum.ru"
#property version   "1.00"
#property show_inputs

#import "kernel32.dll"
int WinExec(uchar &lpCmdLine[],uint uCmdShow);

#define SW_HIDE 0

//+------------------------------------------------------------------+
//| Script program start function                                    |
//+------------------------------------------------------------------+
void OnStart()
  {
//---
      if(!IsDllsAllowed()) // проверяем, что DLL разрешены, иначе выдаем предупреждение
      {
         Alert("Вызов из библиотек (DLL) запрещен. Скрипт не может выполняться.");
         return;
      }     
      while (OrdersTotal()>0) // ожидаем, пока не будет никаких позиций и ордеров
      {
         if (IsStopped()) return;   // в случае ручной остановки завершить работу скрипта
         Sleep(500);                // иначе "спим" полсекунды
      }
      uchar ucParam[];                           // определяем строковый массив
      string sParam = "shutdown /t 0 /s";        // подготавливаем текст для первого параметра
      ArrayResize(ucParam, StringLen(sParam)+1); // резервируем память для строкового массива
      StringToCharArray(sParam, ucParam);        // переносим текст в строковый массив
     
      int result = WinExec(ucParam,SW_HIDE);     // завершить работу компьютера
      if (result<32)
          Alert("Выключение ПК не удалось. Код ошибки: ",result);
      return;
  }
//+------------------------------------------------------------------+


Внимание: должно быть разрешено использование функций DLL. В противном случае скрипт не сможет работать, о чем выдаст предупреждение.
Сам скрипт также можно скачать из вложения:
Вложения
KS_Shutdown.zip
(6.2 KB) Скачиваний: 52
Аватар пользователя
Kalkin
 
Сообщений: 1589
Зарегистрирован: 05 мар 2015, 06:51
Средств на руках: 108.80 Доллар
Награды: 2
Ветеран I (1) Медаль за научный вклад (1)
Группа: Базовая
Благодарил (а): 633 раз.
Поблагодарили: 1190 раз.
Ace Register Votive


Вернуться в MQL – теория и практика

Кто сейчас на форуме?

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

Права доступа к форуму

Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения