1

Тема: AHK: Включение синхронизации с сервером времени.

Здравствуйте. Как вы знаете во всех версиях винды есть "Настройка времени по интернету". Если поставить галочку "Синхронизировать с сервером времени в Интернете" и нажать кнопку "Обновить сейчас", то автоматически выставятся реальные дата и время. Собственно сабж, нужно автоматизировать этот процесс. При запуске скрипта - включить функцию синхронизации если она выключена и выполнить нажатие кнопки "Обновить сейчас". Прошу у вас помощи.

2

Re: AHK: Включение синхронизации с сервером времени.

Я таким пользуюсь:

; #NoTrayIcon
SetBatchLines, -1
SetWinDelay, 0

SS_BLACKRECT := 0x4, AW_HIDE := 0x10000, AW_SLIDE := 0x40000
AW_VER_POSITIVE := 0x4, AW_VER_NEGATIVE := 0x8, Titlehight := 12

if url := SyncLocalTime()
{   
   Gui, -Caption +ToolWindow +Border +AlwaysOnTop +hwndhGui
   Gui, Margin, 15, 10
   
   Gui, Add, Text, % "vText1 y" Titlehight + 10, Время успешно синхронизировано с сервером
   GuiControlGet, Text1, Pos
   
   Gui, Add, Text, % "x0 y0 w" Text1W + 30 " h" Titlehight " +" SS_BLACKRECT   ; серая полоска сверху
   
   Gui, Font,, Verdana
   Gui, Add, Link, % "x" Text1X + 1 " y" Text1Y + Text1H + 2 " w" Text1W " h" Text1H
      , % "<a href=""" . url . """>" . RegExReplace(url, ".+//([^/]+).*", "$1") . "</a>"
   Gui, Font
   
   Gui, Font, s22 q4
   Gui, Add, Text, vText2 c0055AA center y+7 w%Text1W%, % RegExReplace(str := GetTimeString(), "(.*)\R.*", "$1")
   Gui, Font
   
   Gui, Add, Text, vText3 x15 y+22, % RegExReplace(str, ".*\R(.*г).*", "$1.")
   Gui, Add, Button, % "Default h21 w66 y+-21 x" . Text1X + Text1W - 66, OK
   GuiControl, Focus, Button1
   
   Gui, Show, % "Hide w" Text1W + 30
   DetectHiddenWindows, On
   WinGetPos,,, GuiW, GuiH, ahk_id %hGui%
   WinGetPos, X, Y, W, H, ahk_class Shell_TrayWnd
   
   Gui, Show, % "Hide x" X + W - GuiW - 5 " Y" Y - GuiH - 5                      ; указать опцию Hide и не указывать опцию NA
   DllCall("AnimateWindow", Ptr, hGui, UInt, 0, UInt, AW_SLIDE|AW_VER_NEGATIVE)  ; иначе не сработает DllCall("AnimateWindow")
   SetTimer, TimeUpdate, 200
   SetTimer, GuiClose, -6000
}
else
   ExitApp
Return

TimeUpdate:
   str := GetTimeString()
   substr1 := RegExReplace(str, "(.*)\R.*", "$1")
   substr2 := RegExReplace(str, ".*\R(.*г).*", "$1.")
   Loop 2
      if (substr%A_Index% != PrevStr%A_Index%)
         GuiControl,, % "Text" . A_Index + 1, % substr%A_Index%
   Loop 2
      PrevStr%A_Index% := substr%A_Index%
   Return
   
GuiClose:
GuiEscape:
ButtonOK:
   SetTimer, TimeUpdate, Off
   Sleep, 200
   DllCall("AnimateWindow", Ptr, hGui, UInt, 0, UInt, AW_SLIDE|AW_VER_POSITIVE|AW_HIDE)
   ExitApp

SyncLocalTime()
{
   if Time := GetTimeDate(url)   ; в перемменной Time время в формате YYYYMMDDHH24MISS
      res := ChangeLocalTime(Time)
   
   if !(Time && url && res)
   {
      MsgBox, Не удалось установить время. Прежние настройки сохранены.
      Return
   }
   Return url
}

GetTimeDate(ByRef UsedUrl)
{
   oServers := [ {  url:     "http://time100.ru"
                  , pattern: "U)<div class=""text-center maintime"".+</span>.+(\d\d:\d\d:\d\d).+сегодня:.+(\d+\D+\d+?)"  }
               , {  url:     "http://www.timeanddate.com/worldclock/russia/moscow"
                  , pattern: "U)id=ct class=h1>(.+)</span>.+id=ctdat>.+(\d.+)</span>"  } ]
   for k, v in oServers
      ServerString .= v.url . "`n"
                  
   for k, srv in oServers
   {
      if !Ping(server := RegExReplace(url := srv.url, ".+//([^/]+).*", "$1"))
      {
         if (A_Index = oServers.MaxIndex())
         {
            WinClose, ahk_id %hToolTip%
            MsgBox, % "Не удалось сязаться с указанными серверами:`n`n" . ServerString . "`nПроверьте подключение к интернету!"
            Return
         }
         continue
      }
      
      try html := GetHtmlText(url)
      catch
      {
         TrayTip,, Ошибка при подключении к серверу`n%url%
         if (A_Index = oServers.MaxIndex())
         {
            WinClose, ahk_id %hToolTip%
            MsgBox, % "Не удалось сязаться с указанными серверами:`n`n" . ServerString . "`nПроверьте подключение к интернету!"
            Return
         }
         continue
      }
      
      RegExMatch(html, srv.pattern, found)
      if !(found1 && found2)
      {
         MsgBox, 52,, Ошибка парсинга html-текста. Проверьте html c адреса`n`n%url%`nПродолжить?
         IfMsgBox, Yes
            continue
         Return
      }

      for month, v in ["янв", "февр", "мар", "апр", "ма", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"]
         if InStr(RegExReplace(found2, ".+?([а-я]+).*", "$1"), v) = 1
            break
      
      year := RegExReplace(found2, ".+(\d{4}).*", "$1") 
      month := SubStr("0" . month, -1)
      day := SubStr("0" . RegExReplace(found2, "(\d+).+", "$1"), -1)
      hour := RegExReplace(found1, "(\d+).+", "$1")
      min := RegExReplace(found1, ".+?:(\d+).+", "$1")
      sec := RegExReplace(found1, ".+?:.+?:(\d+).*", "$1")
      
      TimeFormatVar := year . month . day . hour . min . sec   ; перемменная в формате YYYYMMDDHH24MISS
      TimeFormatVar += 1, Seconds                              ; прибавляем 1 секунду для компенсации задержки
      if !TimeFormatVar
      {
         MsgBox, 52,, Ошибка парсинга html-текста. Проверьте html c адреса`n`n%url%`nПродолжить?
         IfMsgBox, Yes
            continue
         Return
      }
      UsedUrl := url
      Return TimeFormatVar
   }
}

GetHtmlText(url)
{
   WebRequest := ComObjCreate("WinHttp.WinHttpRequest.5.1")
   WebRequest.Open("GET", url)
   WebRequest.Send()
   Return WebRequest.ResponseText
}
 
Ping(strHost)
{
   oWMI := ComObjGet("winmgmts:")
   Loop 2
      bRet :=  oWMI.Get("Win32_PingStatus.address='" . strHost . "'").StatusCode = 0
   until bRet
   return bRet
}

ChangeLocalTime(Time)
{
   VarSetCapacity(SYSTEMTIME, 16)
   Loop 6
   {
      number := A_Index = 1 ? SubStr(Time, 1, 4) : SubStr(Time, 3 + 2*(A_Index - 1), 2)
      offset := A_Index = 1 ? 0 : A_Index = 2 ? 2 : 2*A_Index
      NumPut(number, SYSTEMTIME, offset, "UShort")
   }
   Return SetLocalTime(&SYSTEMTIME)
}

SetLocalTime(pSYSTEMTIME)
{
   Loop 2   
      if !DllCall("SetLocalTime", Ptr, pSYSTEMTIME) && Error := 1  {
         WinClose, ahk_id %hToolTip%
         MsgBox, Не удалось установить время. Ошибка %A_LastError%
         break
      }
   Return !Error
}

GetTimeString()
{
   month := ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"]
   Return A_Hour ":" A_Min ":" A_Sec . "`n" . A_DDDD . ", " . A_DD . " " . month[A_MM] . " " . A_YEAR . " года"
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3 (изменено: teadrinker, 2017-06-16 02:57:39)

Re: AHK: Включение синхронизации с сервером времени.

А вот так у меня работает системное обновление:

W32TimeFlag_No_Soft := 1, W32TimeFlag_Unknown1 := 2
DllCall("w32time\W32TimeSyncNow", Ptr, 0, UInt, true, UInt, W32TimeFlag_No_Soft | W32TimeFlag_Unknown1)
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

4 (изменено: powercat, 2017-06-16 03:29:20)

Re: AHK: Включение синхронизации с сервером времени.

teadrinker пишет:

Я таким пользуюсь:

Спасибо, работает. Но все таки нужно что-то универсальное и компактное. Ваш второй пример выглядит таким, но к сожалению он у меня не работает(просто ничего не происходит). Возможно из-за того что у нас разные версии винды( у меня 10) ?

//upd.
Вру, кое что происходит. Вообщем все работает если стоит галка "Синхронизировать с сервером времени". Но если её нет, то дата и время не меняются. Как сделать чтобы проверялось наличие этой галки и если её нет - то поставить?

5

Re: AHK: Включение синхронизации с сервером времени.

Не в курсе, последняя функция даже не документирована, нашёл в сети. У меня она отрабатывает только когда разница во времени небольшая, а если дату поменять, возвращает ошибку 4 (The computer did not resync because the required time change was too big).

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

6

Re: AHK: Включение синхронизации с сервером времени.

teadrinker пишет:

Не в курсе, последняя функция даже не документирована, нашёл в сети. У меня она отрабатывает только когда разница во времени небольшая, а если дату поменять, возвращает ошибку 4 (The computer did not resync because the required time change was too big).

Кажется нашел. В реестре:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\Parameters

Type стоит NoSync при выключенной галочке. С включенной NTP.
Получилось:

RegWrite, REG_SZ, HKEY_LOCAL_MACHINE, SYSTEM\CurrentControlSet\Services\W32Time\Parameters, Type, NTP
W32TimeFlag_No_Soft := 1, W32TimeFlag_Unknown1 := 2
DllCall("w32time\W32TimeSyncNow", Ptr, 0, UInt, true, UInt, W32TimeFlag_No_Soft | W32TimeFlag_Unknown1)

И вроде бы все должно работать, но нет. Галка ставится, все вроде включается, но дата обновляться не хочет..

7

Re: AHK: Включение синхронизации с сервером времени.

У меня тоже с этой функцией не обновляется.
Зато так - да:

w32tm /resync /force

8

Re: AHK: Включение синхронизации с сервером времени.

Malcev пишет:

У меня тоже с этой функцией не обновляется.
Зато так - да:

w32tm /resync /force

Не понимаю, это куда вставить надо?

9

Re: AHK: Включение синхронизации с сервером времени.

В CMD.
https://technet.microsoft.com/en-us/lib … 91016.aspx
А если не стоит галочка, то значит сервис не запущен и у меня так работает:

net stop w32time
w32tm /unregister
w32tm /register
net start w32time
w32tm /resync /force

10 (изменено: ypppu, 2017-06-16 07:35:43)

Re: AHK: Включение синхронизации с сервером времени.

Malcev, как это теперь засунуть в скрипт? Чтобы все происходило в скрытом режиме без всяких консолей?

11

Re: AHK: Включение синхронизации с сервером времени.

Не надо цитировать предыдущее сообщение.
Читайте run, runwait.
Узнать сосотояние сервиса можно через WMI:

wmi := ComObjGet("winmgmts:\\" . A_ComputerName . "\root\cimv2")
msgbox % state := wmi.Get("Win32_Service.Name='w32time'").State

12 (изменено: powercat, 2017-06-16 06:03:16)

Re: AHK: Включение синхронизации с сервером времени.

+ открыть спойлер
Process, Priority,, high
Run net stop w32time, , Hide
RunWait w32tm /unregister, , Hide
RunWait w32tm /register, , Hide
RunWait net start w32time, , Hide
RunWait w32tm /resync /force, , Hide

Так вроде работает.

13 (изменено: Malcev, 2017-06-16 21:23:52)

Re: AHK: Включение синхронизации с сервером времени.

А что вы первую команду не с помощью RunWait запускаете?
И чего не проверяете запущен ли сервис?
И зачем прятать свой код?
А вообще наверное правильней действовать по такому алгоритму:
1) Проверяем зарегестрирован ли Windows Time сервис.
2) Если не зарегестрирован - регестрируем и перезагружаем компьютер, так как дальнейшие команды без перезагрузки не срабтывают.
3) Проверяем состояние  сервиса, если он стоит, то проверяем его автозапуск, если автозапуск выключен, то включаем его и запускаем w32time.
4) Задаём серверы и запускаем синхронизацию.

ComObjError(false)
wmi := ComObjGet("winmgmts:\\" . A_ComputerName . "\root\cimv2")
w32time := wmi.Get("Win32_Service.Name='w32time'")
if A_LastError
{
   RunWait w32tm /register, , Hide
   msgbox нужен рестарт компьютера
   ExitApp
}
state := w32time.state
if (state = "stopped")
{
   StartMode := w32time.StartMode
   if (StartMode = "Disabled")
      w32time.ChangeStartMode("Automatic")
   w32time.StartService
}
RunWait w32tm /config /update /manualpeerlist:"0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org" /syncfromflags:MANUAL /reliable:yes, , Hide
RunWait w32tm /resync /force, , Hide

14

Re: AHK: Включение синхронизации с сервером времени.

Malcev пишет:
net stop w32time
w32tm /unregister
w32tm /register
net start w32time
w32tm /resync /force

Вообще, по-моему не очень вариант. unregister/register сбрсывает все данные из реестра на дефолтные. А у меня после экспериментов с этим кодом после перезагрузки вообще пропал куст HKLM\SYSTEM\CurrentControlSet\services\W32Time, благо бэкап недавно делал.
Попробую написать вариант через winapi, если получится — выложу.

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

15

Re: AHK: Включение синхронизации с сервером времени.

А код из 13 поста работает?
Там вроде ничего удаляться или сбрасываться не должно.

16

Re: AHK: Включение синхронизации с сервером времени.

Не заметил его.
А что делает строчка

RunWait w32tm /config /update /manualpeerlist:"0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org" /syncfromflags:MANUAL /reliable:yes, , Hide

?

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

17

Re: AHK: Включение синхронизации с сервером времени.

Указывает, что получаем новые сервера для синхронизации.
Там, как я понял, они каждый час меняются.
http://www.pool.ntp.org/ru/use.html
Без этой строчки у меня иногда скрипт выводил, что ресинхронизация невозможна, так как нету источников.

18

Re: AHK: Включение синхронизации с сервером времени.

Не совсем понял. У меня сервера перечислены здесь:

http://i.imgur.com/GEmIkh3.jpg

А текущий указан в реестре:

http://i.imgur.com/dZsbnrV.jpg

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

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

19

Re: AHK: Включение синхронизации с сервером времени.

У меня в коде ошибка, забыл утроить кавычки в "0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org".

ComObjError(false)
wmi := ComObjGet("winmgmts:\\" . A_ComputerName . "\root\cimv2")
w32time := wmi.Get("Win32_Service.Name='w32time'")
if A_LastError
{
   RunWait w32tm /register, , Hide
   msgbox нужен рестарт компьютера
   ExitApp
}
state := w32time.state
if (state = "stopped")
{
   StartMode := w32time.StartMode
   if (StartMode = "Disabled")
      w32time.ChangeStartMode("Automatic")
   w32time.StartService
}
RunWait w32tm /config /update /manualpeerlist:"""0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org""" /syncfromflags:MANUAL /reliable:yes, , Hide
RunWait w32tm /resync /force, , Hide

0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org - тут идет перечисление серверов.
Если с первым не будет связи, то свяжется со вторым.
Если хочется использовать time.windows.com, то можно его добавить в список первым.

20

Re: AHK: Включение синхронизации с сервером времени.

Так вроде хорошо работает!

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

21 (изменено: teadrinker, 2017-06-17 04:47:24)

Re: AHK: Включение синхронизации с сервером времени.

Утраивание кавычек, по-моему, не нужно — это строка, и они трактуются буквально.

Malcev пишет:

msgbox нужен рестарт компьютера

А точно он нужен? В этом примере же и без того как-то работало?

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

22

Re: AHK: Включение синхронизации с сервером времени.

Утраивание нужно, так как без него будет выходить ошибка, я так проверял:
Не работает:

runwait, cmd.exe /k w32tm /config /update /manualpeerlist:"0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org" /syncfromflags:MANUAL /reliable:yes

Работает:

runwait, cmd.exe /k w32tm /config /update /manualpeerlist:"""0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org""" /syncfromflags:MANUAL /reliable:yes

Работает:

runwait, cmd.exe /k w32tm "/config /update /manualpeerlist:""0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org"" /syncfromflags:MANUAL /reliable:yes"

И без рестарта у меня выходят ошибки:
Допустим удаляем сервис w32time, перезагружаем компьютер.
Регистрируем сервис, запускаем его и получаем ошибку:

Error 1290: The service start failed since one or more services in the same process have an incompatible service SID type setting.  A service with restricted service SID type can only coexist in the same process with other services with a restricted SID type. If the service SID type for this service was just configured, the hosting process must be restarted in order to start this service.

Тут вроде написано как это сделать, но у меня при повторном перезапуске сервера выводит ошибку Access is denied. (0x80070005).
http://sanotes.ru/w32tm-resync-access-i … x80070005/

23

Re: AHK: Включение синхронизации с сервером времени.

У меня первые два варианта выдают одинаковую ошибку:

Следующие аргументы были непредвиденными:

"0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org"

Третий тоже не работает:

Неизвестная команда /config /update /manualpeerlist:"0.pool.ntp.org.

Зато с сервером, прописанным у меня, всё в порядке:

runwait, cmd.exe /k w32tm /config /update /manualpeerlist:"time-a.nist.gov" /syncfromflags:MANUAL /reliable:yes

Команда выполнена успешно.

С одинарными кавычками.

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

24

Re: AHK: Включение синхронизации с сервером времени.

Интересно.
На 64-битном ahk надо запускать с одинарными кавычками:

runwait, cmd.exe /k w32tm /config /update /manualpeerlist:"0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org" /syncfromflags:MANUAL /reliable:yes

А на 32-битном с тройными:

runwait, cmd.exe /k w32tm /config /update /manualpeerlist:"""0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org""" /syncfromflags:MANUAL /reliable:yes

Баг что ли?

25

Re: AHK: Включение синхронизации с сервером времени.

У меня с моим сервером на 32-битном работает так же.

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

26

Re: AHK: Включение синхронизации с сервером времени.

Работает, потому что с одним сервером кавычки вообще не нужны:

manualpeerlist:<peers>—Sets the manual peer list to <peers>, which is a space-delimited list of Domain Name System (DNS) and/or IP addresses. When you are specifying multiple peers, this option must be enclosed in quotation marks (“).

https://technet.microsoft.com/en-us/lib … s.11).aspx

27

Re: AHK: Включение синхронизации с сервером времени.

А сейчас вот у меня даже с моим сервером не работает:

Следующие аргументы были непредвиденными:
time-a.nist.gov

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

28

Re: AHK: Включение синхронизации с сервером времени.

У меня работает так и на 32-бит и на 64:

runwait, cmd.exe /k w32tm /config /update /manualpeerlist:time-a.nist.gov /syncfromflags:MANUAL /reliable:yes

29

Re: AHK: Включение синхронизации с сервером времени.

А, нет, неправильно просто написал, перед сервером пробел поставил. С моим работает.

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

30

Re: AHK: Включение синхронизации с сервером времени.

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

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

31

Re: AHK: Включение синхронизации с сервером времени.

Ну так я о чём.
С одним сервером кавычки не нужны.
Если же список серверов, то нужны кавычки (в 26 посте я привёл ссылку).
И самое интересное, что если запускать скрипт через ahk64 бит, то указываешь одинарные кавычки, что логично, т ак как это строка.
Но если же запускать через ahk32 бит, то нужно эти кавычки утраивать.

32

Re: AHK: Включение синхронизации с сервером времени.

Ага, подтверждаю.

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

33

Re: AHK: Включение синхронизации с сервером времени.

teadrinker пишет:

У меня первые два варианта выдают одинаковую ошибку

Похоже, лишний пробел вставлял.

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

34

Re: AHK: Включение синхронизации с сервером времени.

Malcev пишет:

Но если же запускать через ahk32 бит, то нужно эти кавычки утраивать.

Действительно, похоже на баг. Попробуй спросить на форуме, интересно, в чём проблема.

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

35

Re: AHK: Включение синхронизации с сервером времени.

Отписал. Посмотрим, что ответят.

36 (изменено: teadrinker, 2017-06-17 18:56:10)

Re: AHK: Включение синхронизации с сервером времени.

lexikos пишет:

I would suggest testing the following:

    Run directly from a 32-bit command prompt. That is, launch C:\Windows\SysWow64\cmd.exe and paste your command line there.
    Run the 64-bit command processor from AutoHotkey 32-bit. That is, RunWait C:\Windows\SysNative\cmd.exe ....
    Run w32tm 32-bit directly (see below). w32tm is an executable; cmd.exe is not needed except to force the output to remain on screen (but you can get around that).
    Run w32tm 64-bit directly. That is, RunWait C:\Windows\SysNative\w32tm.exe ....

Имхо, сюда незачем примешивать ещё и битность cmd.exe, она ведь в реальности не используется. Протестировать можно так:

cmd = w32tm /config /update /manualpeerlist:"0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org" /syncfromflags:MANUAL /reliable:yes
MsgBox, % StdOut(cmd, "cp866")

StdOut(sCmd, encoding)
{
   static STARTF_USESTDHANDLES := 0x100, CREATE_NO_WINDOW := 0x08000000
   
   DllCall("CreatePipe", PtrP, hStdInRd, PtrP, hStdInWr, UInt, 0, UInt, 0)
   DllCall("CreatePipe", PtrP, hStdOutRd, PtrP, hStdOutWr, UInt, 0, UInt, 0)
   DllCall("SetHandleInformation", Ptr, hStdInRd, UInt, 1, UInt, 1)
   DllCall("SetHandleInformation", Ptr, hStdOutWr, UInt, 1, UInt, 1)
   
   VarSetCapacity(pi, A_PtrSize*2 + 8, 0)
   NumPut( VarSetCapacity(      si, A_PtrSize*4 + 4*8 + A_PtrSize*5, 0), si )
   NumPut(STARTF_USESTDHANDLES, si, A_PtrSize*4 + 4*7)
   NumPut(hStdInRd            , si, A_PtrSize*4 + 4*8 + A_PtrSize*2)
   NumPut(hStdOutWr           , si, A_PtrSize*4 + 4*8 + A_PtrSize*3)
   NumPut(hStdOutWr           , si, A_PtrSize*4 + 4*8 + A_PtrSize*4)

   DllCall("CreateProcess", UInt, 0, Ptr, &sCmd, UInt, 0, UInt, 0, Int, True, UInt, CREATE_NO_WINDOW, UInt, 0, UInt, 0, Ptr, &si, Ptr, &pi)
   
   for k, v in [NumGet(pi, 0), NumGet(pi, A_PtrSize), hStdOutWr, hStdInRd, hStdInWr]
      DllCall("CloseHandle", Ptr, v)

   VarSetCapacity(sTemp, 4095)
   while DllCall("ReadFile", UInt, hStdOutRd, Ptr, &sTemp, UInt, 4095, UIntP, nSize, UInt, 0)
      sOutput .= StrGet(&sTemp, nSize, encoding)
   DllCall("CloseHandle", Ptr, hStdOutRd)
   Return sOutput
}

А чтобы сработало без ошибок, можно проверять оба варианта:

ComObjError(false)
w32time := ComObjGet("winmgmts:").Get("Win32_Service.Name='w32time'")
if A_LastError
{
   RunWait w32tm /register,, Hide
   msgbox нужен рестарт компьютера
   ExitApp
}
state := w32time.state
if (state = "stopped")
{
   StartMode := w32time.StartMode
   if (StartMode = "Disabled")
      w32time.ChangeStartMode("Automatic")
   w32time.StartService
}
for k, quotes in ["""", """"""""]  {
   RunWait, % "w32tm /config /update /manualpeerlist:"
             . quotes . "0.pool.ntp.org 1.pool.ntp.org 2.pool.ntp.org 3.pool.ntp.org" . quotes
             . " /syncfromflags:MANUAL /reliable:yes",, Hide
;  MsgBox, % ErrorLevel
} until !ErrorLevel
RunWait w32tm /resync /force,, Hide
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

37

Re: AHK: Включение синхронизации с сервером времени.

teadrinker пишет:

А чтобы сработало без ошибок, можно проверять оба варианта:

Вот этот вариант очень хорошо работает, протестировал на windows 7/10 x32 системах. Спасибо за помощь!