Как программно узнать, когда ОС полностью загрузилась

Программирование на Visual Basic, главный форум. Обсуждение тем программирования на VB 1—6.
Даже если вы плохо разбираетесь в VB и программировании вообще — тут вам помогут. В разумных пределах, конечно.
Правила форума
Темы, в которых будет сначала написано «что нужно сделать», а затем просьба «помогите», будут закрыты.
Читайте требования к создаваемым темам.
Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 03.11.2020 (Вт) 11:36

Здравствуйте!
Скажите: как с помощью WMI или еще как-то узнать, когда операционная система полностью загрузилась?

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 03.11.2020 (Вт) 13:48

Хочу дополнить свой вопрос...
Где-то в интернете находил информацию, что есть такие службы в системе, которые сообщают время загрузки ОС и отображают ее в миллисекундах. Логично предположить, что если служба получает такую информацию, значит, есть какая-то функция или класс, которые определяют, что система полностью загружена и останавливают этот самый «секундомер». Так вот что это за функция??? Подскажите, пожалуйста.

bon818
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 267
Зарегистрирован: 29.08.2009 (Сб) 4:49
Откуда: Ташкент

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение bon818 » 04.11.2020 (Ср) 6:01

Vova_2581 писал(а):Логично предположить, что если служба получает такую информацию, значит, есть какая-то функция или класс, которые определяют, что система полностью загружена и останавливают этот самый «секундомер». Так вот что это за функция??? Подскажите, пожалуйста.

Нет такого. Есть только GetTickCount().

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 04.11.2020 (Ср) 8:42

bon818 писал(а):Есть только GetTickCount().

Если я не ошибаюсь, то эта функция кажется считает время работы ОС с момента загрузки, и считает непрерывно. Так а как понять, что система уже загрузилась???

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 04.11.2020 (Ср) 10:35

Есть такая утилита Glary - она показывает время загрузки. Как она это делает??
Glary Utilites.jpg
Glary Utilites.jpg (53.25 Кб) Просмотров: 3929

Proxy
Профессор VB наук
Профессор VB наук
Аватара пользователя
 
Сообщения: 2941
Зарегистрирован: 31.08.2007 (Пт) 4:41

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Proxy » 04.11.2020 (Ср) 11:10

Если это время не совпадает со временем из диспетчера задач, то наверняка с момента запуска какой-нибудь своей службы считает. Нет такого понятия, как "система полностью загрузилась", в планировщике всегда что-нибудь на будущее найдётся, так что последняя надёжная точка по времени — это вход пользователя в систему (если речь про десктоп).
Follow the white rabbit.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 04.11.2020 (Ср) 13:33

В инете пишут, что есть команда eventvwr (Win7) и там через журналы можно дойти до "Длительность загрузки" в миллисекундах.
Вот тут подробней...
Как узнать время загрузки и выключения Windows?
windows.jpg
windows.jpg (48.9 Кб) Просмотров: 3922

Так вот, мне бы как-то получить все тоже самое только программно. Как это сделать?

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 12.11.2020 (Чт) 23:06

Короче, решил воспользоваться советом Хакера из прошлого топика...
Скачал Glary Utilites Pro 5, а потом скачал Dependency Walker. Итак, по-порядку...
Установил Glary Utilites, и среди целой кучи разных файлов (C:\Program Files (x86)\Glary Utilities 5), нашел одну интересную библиотеку под названием BootTime.dll - именно ее я открыл в Dependency Walker и получил небольшой список экспортируемых функций этой библиотеки. Среди них сразу бросилась в глаза функция GetSystemLoadTime... Возможно именно она и возвращает время загрузки системы?
Depends.jpg
Depends.jpg (109.8 Кб) Просмотров: 3875

Появилась идея: для получения времени загрузки, просто воспользоваться этой функцией данной, надеюсь, Native Dll библиотеки.
Вопрос теперь в том, как мне ее задекларировать в VB и получить описание IN/OUT параметров??? Подскажите, пожалуйста.

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

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Хакер » 12.11.2020 (Чт) 23:27

Vova_2581 писал(а):Появилась идея: для получения времени загрузки, просто воспользоваться этой функцией данной, надеюсь, Native Dll библиотеки.
Вопрос теперь в том, как мне ее задекларировать в VB и получить описание IN/OUT параметров??? Подскажите, пожалуйста.

Глянуть под отладчиком, как она вызывается, что передаётся, что возвращается. Или просто разреверсить её и отвязаться от DLL.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

The trick
Постоялец
Постоялец
 
Сообщения: 781
Зарегистрирован: 26.06.2010 (Сб) 23:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение The trick » 12.11.2020 (Чт) 23:37

Vova_2581 писал(а):GetSystemLoadTime

Функция проверяет тайминги процесса lsass.exe через GetProcessTimes.
UA6527P

Teranas
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 224
Зарегистрирован: 13.12.2008 (Сб) 4:26
Откуда: Новосибирск

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Teranas » 13.11.2020 (Пт) 9:34

Обычно использую проверку загрузку процессора, если она ниже 10%, значит можно запускать свою фигню.
Всегда и везде работает. Хотя нужно понимать, что проверка может попасть на промежуток между экстремумами.
С уважением, Андрей.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 13.11.2020 (Пт) 19:58

Хакер писал(а):Глянуть под отладчиком, как она вызывается, что передаётся, что возвращается. Или просто разреверсить её и отвязаться от DLL.

Мне не совсем понятно как слово, так и сам механизм, как вы назвали - "разреверсить". Немного почитал Гугл из которого стало ясно, что это что-то типа дезасемблирования, но я в ассемблере не силен, к тому же в инете пишут, что можно нарваться на обфускацию кода - сейчас это модно.
Как тогда быть???
The trick
Teranas

Вы имеете ввиду, что можно проверять загрузку CPU процесса lsass.exe и если она упала до "плинтуса" в этот момент снять показания GetTickCount() - это и будет время загрузки??? Я правильно Вас понимаю??? :scratch:

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

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Хакер » 13.11.2020 (Пт) 20:41

Vova_2581 писал(а):Мне не совсем понятно как слово, так и сам механизм, как вы назвали - "разреверсить". Немного почитал Гугл из которого стало ясно, что это что-то типа дезасемблирования, но я в ассемблере не силен, к тому же в инете пишут, что можно нарваться на обфускацию кода - сейчас это модно.

Во-первых, не можно, во-вторых, в момент вызова функции из DLL точно никаких последствий обфускации не будет, которые бы влияли на ответ на поставленный вопрос.

Vova_2581 писал(а):Вы имеете ввиду, что можно проверять загрузку CPU процесса lsass.exe и если она упала до "плинтуса" в этот момент снять показания GetTickCount() - это и будет время загрузки??? Я правильно Вас понимаю???

Нет, речь идёт не о загрузке CPU, а о счётчиках времени, которые возвращает GetProcessTimes для процесса lsass.

Вообще, вопрос бесперспективный в своём текущем виде.

Потому что нет такого монолитного понятия «система», и уж тем более нет такого понятия или момента, как «система полностью загружена».

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

Поэтому вопрос определения времени загрузки всецело зависит от определения того, что значит «система полностью загружена». В зависимости от того, к каким действиям и внутренним факторам будет привязано это определение, таким будет и ответ.

Teranas писал(а):Обычно использую проверку загрузку процессора, если она ниже 10%, значит можно запускать свою фигню.

А что значит «своя фигня» и почему её нельзя запускать раньше? Если это какая-то ресурсоёмкая фигня, и смысл всех этих мер, чтобы нагрузка на машину от своей фигни не наложилась с нагрузкой от чего-то другого, то такой подход заранее обречён, потому что он порождает race condition.

Если какие-то приложения будут «благоприятного момента» чтобы начать делать что-то ресурсоёмкое, чтобы это действие свершилось быстро, то в реальной жизни несколько таких программ будут детектировать наступление благоприятного времени почти одновременно, и будут свою ресурсоёмкую задачу начинать делать тоже практически одновременно, и будут мешать друг-другу. А значит это ничем не будет отличаться от подхода, когда прогарммы не ждут благоприятного момента, а просто начинают ресурсоёмкую работу сразу же, как приспичит.

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

Это в случае централизированного подхда. Но здесь, как я понимаю, пишется приложение, которое само хочет делать что-то ресурсоёмкое независимо от других, а не координировать других. Возможен был бы и децентрализованный подход, где с применением алгоритмов выбора лидера выбирался бы один процесс, которому доступна привилегии воспользоваться простаивающими ресурсами. Но все процессы должны играть по одинаковым правилам при таком децентрализованном подходе.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 14.11.2020 (Сб) 11:44

Ну, хорошо, если система не монолитна (согласен), то на какие же тогда опорные точки отсчета времени опираются Glary и eventvwr что все таки отображают время загрузки??? Они берут за основу процесс авторизации lsass и используют функцию GetProcessTimes так что ли?? :?:
Да... и вы так и не ответили, что значит "разреверсить"?? Для этого процесса нужны какие-то дополнительные хакерские программы??

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

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Хакер » 14.11.2020 (Сб) 15:50

Vova_2581 писал(а):что все таки отображают время загрузки???

Что вообще такое «время загрузки»? Это момент времени, когда произошла или когда закончилась загрузка? Или это количество времени, которое потребовалось на осуществление загрузки?

Vova_2581 писал(а):Да... и вы так и не ответили, что значит "разреверсить"?? Для этого процесса нужны какие-то дополнительные хакерские программы??

Разреверсить — значит провести реверс-инжениринг. Реверс-инжениринг, это процесс, обратный типичному процессу разработки чего бы то ни было. Это восстановление чертежа и проектной документации по готовой детали. Это восстановление химической формулы по готовому веществу. Восстановление нот/партитур по готовому муз. произведению. Воссоздание схемы, рассчётов по готовой плате/электронному устройству в случае электроники.

В случае программирование это восстановление исходного кода по машинному коду. Не всегда речь идёт о восстановлении прямо таки исходного кода, иногда можно органичиться пониманием принципа работы (как в нашем случае).

Vova_2581 писал(а):Для этого процесса нужны какие-то дополнительные хакерские программы??

«Дополнительные» и «хакерские» — очень сомнительные определения. К чему дополнительные? Все прикладные программы уже по определению дополнительные, потому что они прилагаются (или прикладываются?) к операционной системе. Назвать отладчик или дизассемблер хакерским тоже нельзя, ведь отладчиком нормально пользоваться любому разработчику, который хочет отладить свой (или не свой) код.

Да, нужен какой-нибудь отладчик. Вариантов множество, включая написание своего собственного, но наиболее удачным выбором (особенно для начинающего) будет OllyDbg.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 14.11.2020 (Сб) 19:02

Хакер писал(а):...это количество времени, которое потребовалось на осуществление загрузки?

Именно так!
Хакер писал(а):Да, нужен какой-нибудь отладчик. Вариантов множество, включая написание своего собственного, но наиболее удачным выбором (особенно для начинающего) будет OllyDbg.

Ну я попробую, хотя не знаю получится ли???

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

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Хакер » 14.11.2020 (Сб) 22:29

Vova_2581 писал(а):Именно так!

В таком ключе вопрос становится в два раза хуже: мало того, что совершенно непонятно, что считать моментом конца загрузки, непонятно также считать, что считать моментом начала.

Момент нажатия кнопки Power On на системном блоке?
Момент окончания POST?
Момент запуска кода из бутсектора?
Момент запуска NTLDR?
Момент перехода в защищённый режим?
Момент вызова KiSystemStartup в ntoskrnl.exe?
Момент запуска графической подсистемы?
Момент запуска winlogon?
Момент входа пользователя в систему и запуска explorer.exe?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 15.11.2020 (Вс) 9:06

Хакер писал(а):...непонятно, что считать моментом конца загрузки, непонятно также считать, что считать моментом начала.

Так вот и я о том же... То же не понимаю... :?:

В общем, открыл я BootTime.dll в дебаггере OllyDbg и получил такую себе картину: функция GetSystemLoadTime вызывается по адресу 743F12C0
Если не углубляться в сам запудренный ассемблер, а посмотреть, какие API вызывает эта функция, то очевидно, что в основном все из ядра Kernel32... Как и писалось ранее The trick - функция отслеживает процесс авторизации пользователя lsass.exe. Для этого делает снимки процессов SnapShot через CreateToolHelp32SnapShot, потом открывает процесс, видимо, для получения его указателя для GetProcessTimes и еще вызывает получение системного времени и также функцию счетчика времени работы системы в целом GetTickCount. И еще SystremTimeToFileTime. Короче, понятно что вызывается, но туманно понятен сам алгоритм. :scratch:
BootTime.jpg

Пробовал тупо вызвать...
Код: Выделить всё
Private Declare Function GetSystemLoadTime Lib "BootTime.dll" () As Long

Private Sub Form_Load()
MsgBox GetSystemLoadTime
End Sub

Получил разные цифры типа: 7712... 7105... 6971... и т.д.
Можно предположить, что это миллисекунды, но они все равно не совпадают с данными команды вызова журналов eventvwr (Win7). Вот картинка с того же компа... Длительность загрузки...
TimeLoad.jpg
TimeLoad.jpg (163.9 Кб) Просмотров: 3802

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение ALX_2002 » 16.11.2020 (Пн) 11:51

В общем, я как любитель VBS / JS + WSH, решил попробовать собрать подобие на VBS + WMI.

Осторожно, ниже хреновый код, который не одобрит Хакер :oops: :D , но возможно что-то из него пригодится или наведёт на мысли.

(!) Процесс должен быть запущен с правами администратора, чтобы иметь возможность сделать запись в реестр.

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

Код: Выделить всё
Option Explicit

MsgBox GetBootTime()

Function GetBootTime()
   Const HKEY_LOCAL_MACHINE  = &H80000002
   Dim objSWbemServices, objSWbemObjectSet, blnKeyCreated
   'Путь в реестре, где необходимо создать раздел
   Const REGISTRY_KEY = "SYSTEM\CurrentControlSet\Services\EventLog\Microsoft-Windows-Diagnostics-Performance/Operational"
   'Объект для подключения к WMI
   Set objSWbemServices = CreateObject("WbemScripting.SWbemLocator").ConnectServer()
   With objSWbemServices.Get("StdRegProv")
      'Проверка существования ключа в реестре
      If .EnumKey(HKEY_LOCAL_MACHINE,REGISTRY_KEY) <> 0 Then
         'Если ключа нет, то создаём
         If .CreateKey(HKEY_LOCAL_MACHINE,REGISTRY_KEY) = 0 Then
            blnKeyCreated = True
         Else
            'Если не создался, значит печаль тоска
            Err.Raise vbObjectError + 1, "GetBootTime", "Not enough privileges"
         End if
      End if
      'Выполняем поиск нужного события в логах
      With objSWbemServices.ExecQuery("SELECT * FROM Win32_NtLogEvent WHERE Logfile='Microsoft-Windows-Diagnostics-Performance/Operational' AND EventCode = 100")
         If .Count > 0 Then GetBootTime = .ItemIndex(0).InsertionStrings(5)
      End With
      'Если ключик был создан нами, то чистим его по концу работы
      If blnKeyCreated Then .DeleteKey HKEY_LOCAL_MACHINE, REGISTRY_KEY
   End With
End Function

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 16.11.2020 (Пн) 22:05

Хакер, тише, тише!.. :silent: Не спугните "зверя" - мега гуру! ALX_2002 - Вы кажется та сама "соломинка" за которую мы все хотим ухватится. :D
Код работает! И без прав админа...
Project.jpg
Project.jpg (170.42 Кб) Просмотров: 3762

TimeLoad.jpg
TimeLoad.jpg (177.84 Кб) Просмотров: 3762

Только я не совсем понял, зачем предварительно нужно делать запись в реестр, если ставится задача по идее прочесть уже существующие данные в реестре??? Че-та я вообще запутался. :roll:
Всегда поражался теми, кто в совершенстве владеет технологиями WMI, WSH и т.д. По Вашим кодам можно учится!
Вот уж действительно гуру и мега! :!:
Если подытожить, - то эта задача решена! Но вопрос немного в другом (по названию топика...), как понять, что система загрузилась? Может что-то сможет нам сказать могучий WMI???

ALX_2002
Мега гуру
Мега гуру
 
Сообщения: 2054
Зарегистрирован: 25.11.2002 (Пн) 20:03

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение ALX_2002 » 17.11.2020 (Вт) 11:14

Vova_2581, рад, что пригодилось, но думаю есть пара моментов, которые стоит пояснить.

Вы кажется та сама "соломинка" за которую мы все хотим ухватится.

:D Благодарю, но на счёт "все", позволю себе посомневаться. Уверен, что если бы у Хакера или The Trick-а и остальных мегамозгов этого форума была необходимость решить подобную задачу, то они бы это сделали за пару часов, если не быстрее. Провели бы реверсинжиниринг кода или под отладчиком выснили, что куда обращается. Я очень часто жалею, что не обладаю этими знаниями, поэтому приходится городить подобный хламокод.

Код работает! И без прав админа...

Подозреваю, что у вас отключен UAC. Если он запущен, то процессы запущенные под пользователем не имеют прав на запись в реестр в ветку HKLM и ещё ограничены кучей запретов. Так как по умолчанию он на системах включен, я исходил из общего случая :D

Кстати, в интернете полно примеров незаметного обхода UAC.
1) https://habr.com/ru/post/430498/
2) https://github.com/Vozzie/uacscript/blob/master/bypass.vbs
3) https://github.com/rootm0s
Возможно что-то из них можно попользовать и для этого случая.

Только я не совсем понял, зачем предварительно нужно делать запись в реестр, если ставится задача по идее прочесть уже существующие данные в реестре??? Че-та я вообще запутался. :roll:

Вот тут то и начинается самое интересное. Для работы с логами в Windows есть несколько WMI объектов. Для получения списка журналов, которые нужно учитывать при запросах, все они ориентируются на раздел реестра "SYSTEM\CurrentControlSet\Services\EventLog\". Но как назло, мелкомягкие не внесли в этот раздел ветку Microsoft-Windows-Diagnostics-Performance/Operational в которой как раз и лежат логи, которые содержат события с кодом 100. В результате приходится искусственно добавлять эту ветку перед тем как сделать запрос. Вот тут хорошо об этом написано. Как я и писал ниже, предполагаю, что эту проверку можно "обмануть" перехватив обращение в реестр, но... стоит ли оно того, не уверен. Гораздо более правильным подходом был бы метод предложенный Хакером.

как понять, что система загрузилась? Может что-то сможет нам сказать могучий WMI???

Вот тут человек озадачился как раз выяснением что куда и как http://www.happysysadm.com/2014/07/windows-boot-history-and-boot.html.
Если всё-таки не озадачиваться реверсом кода, то есть ещё несколько альтернатив получения информации
1) Получение через PowerShell через Get-WinEvent (описано в статье по ссылке выше).
2) Либо через вызов встроенной Windows утилиты wevtutil
Код: Выделить всё
wevtutil qe Microsoft-Windows-Diagnostics-Performance/Operational /rd:true /c:1 /f:xml /q:"* [System [(EventID = 100)]]" /e:Events
, но она опять же требует прав админа, если включен UAC

Код: Выделить всё
Всегда поражался теми, кто в совершенстве владеет технологиями WMI, WSH и т.д. По Вашим кодам можно учится!

Ой не рекомендую :D ! Если Хакер увидит этот код, заранее "вангую", он скажет:
1) Ненадёжность подхода - В журнале может не быть этих событий (вдруг его почистили), может не быть прав доступа на запись в реестр, если мы под ограниченным пользователем.
2) К тому же это недокументированный подход, раз по умолчанию WMI объекты не видят этот журнал.
3) Код написан без учёта проверок на падение
If .Count > 0 Then GetBootTime = .ItemIndex(0).InsertionStrings(5)
. А если Count <=0, то что ?? У Функции не задан тип возвращаемых данных. Почему константа объявлена внутри функции ? Для переменных внутри функции не заданы типы. В коде используется позднее связывание, единственная ошибка, которая генерится в функции по условию совершенно не отражает реальную причину несрабатывания кода.... В общем facepalm !
3) Зачем решать поставленную задачу обходными путями, если за всем этим всё равно стоят Api, которые можно вызвать и не изобретать велосипед ?!

И будет совершенно прав !

P.S Для чего я выложил этот код, если сам понимаю, что так делать нельзя ? Надеюсь, что Хакер или остальные мегамозги увидят и скажут - "ДА ! ЁМАЁ ! ШО Ж ВЫ ДЕЛАЕТЕ ! РУКИ БЫ ПООТРЫВАТЬ И ОБРАТНЫМ КОНЦОМ ВСТАВИТЬ !" и сделают какую-нибудь статью для чайников - базовые основы реверсинга на конкретных примерах и распишут как, например, в этом случае добраться до истины и узнать какую API и как дёргать, чтобы решить эту задачу.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 17.11.2020 (Вт) 17:54

Ну, Вы прямо таки себя так разругали. Может быть и есть какие-то неучеты, но все равно Ваш код довольно таки любопытный, спасибо за публикацию. Я даже не думал, что WMI может работать с реестром. Хотя есть еще и WScript.Shell, даже не знаю, что лучше? Я обязательно воспользуюсь примером Вашего кода для одного своего проекта. Мне нужно сделать запись в реестр в нестандартную, как для VB область, и не очень хочется делать это через громоздкие API. Как раз искал какое-нибудь более простое решение и Ваш код просто таки находка! Можно проверить ветку, записать и удалить – все что нужно! Обязательно поэкспериментирую. Если будут вопросы, надеюсь с Вами пообщаться в личке по этому поводу. :roll:

Что касается Хакера, ну так вот видите... не все так просто, как говорится, есть вопросы... Я ведь не даром привел примеры команд, которые читают логи... и так же китайскую утилиту Glary – они все показываю время загрузки Windows, а это автоматически означает, что есть некая временнАя «точка A», которая берется (условно) за начало отсчета и есть условная «точка Б», которая берется за конец отсчета. То есть, система начала загрузку в «A» момент времени, и система уже загрузилась в «Б» момент времени.
Ну, а дальше Б - A = С миллисекунд. Вот что это за точки, непонятны даже Хакеру.

Подозреваю, что у вас отключен UAC

Да неудобный он, потому обычно все его отключают, и у меня так же. Ваши подозрения оправдались. :)
Спасибо за дальнейшие пояснения! Тем не менее вопрос остается открытым.
Как показало «вскрытие» библиотеки BootTime.dll из пакета Glary, и как говорилось тут другими участниками, экспортируемая функция GetSystemLoadTime этой библиотеки, возвращающая время загрузки, отслеживает завершение загрузки процесса авторизации lsass.exe.
Так может алгоритм такой... :idea:
1) Отслеживать завершение загрузки lsass.exe – это будет наша «точка Б».
2) Как только загрузка завершилась, снимаем показания GetTickCount и запоминаем их – это будет наша «точка A».
3) Б – A = С время...
Может быть так? :?:

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

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Хакер » 18.11.2020 (Ср) 4:04

Vova_2581 писал(а):и так же китайскую утилиту Glary – они все показываю время загрузки Windows, а это автоматически означает, что есть некая временнАя «точка A», которая берется (условно) за начало отсчета и есть условная «точка Б», которая берется за конец отсчета. То есть, система начала загрузку в «A» момент времени, и система уже загрузилась в «Б» момент времени.
Ну, а дальше Б - A = С миллисекунд. Вот что это за точки, непонятны даже Хакеру.


Ладно там Хакер. Если тебе самому неведомо, каким моментам соответствуют точки А и Б, то зачем тебе разница между этими двумя точками? Ты сам не знаешь, что хочешь замерить, но замеренная величина тебе зачем-то нужна. Зачем? Куда будешь её применять?

Мне это напоминает андекдот:
Пилот бортинженеру: Приборы?
Бортинженер пилоту: 140!
Пилот бортинженеру: Что «140!»?
Бортинженер пилоту: А что «приборы»?


А что касается WMI, то, например, под Windows XP этот код не работает, и, более того, там в журнале событий даже близко нет никакой такой записи. И не надо говорить, что XP устарела — она не смотря на это точно так же загружается, и значит такая величина, как время загрузки, имеет для неё смысл.

Это я к тому, что ладно бы был какой-то стандартизированный способ замера этого времени. А вы тут привязались к произвольно выбранному способу.

Vova_2581 писал(а):Как показало «вскрытие» библиотеки BootTime.dll из пакета Glary, и как говорилось тут другими участниками, экспортируемая функция GetSystemLoadTime этой библиотеки, возвращающая время загрузки, отслеживает завершение загрузки процесса авторизации lsass.exe.

Отслеживает завершение? Я не реверсил, но ничего такого там скорее всего нет. Там определяется время запуска этого процесса — разница между моментом запуска и «рождеством Христа», а не разница между началом работы процесса и концом работы.

Vova_2581 писал(а):Как только загрузка завершилась, снимаем показания GetTickCount и запоминаем их – это будет наша «точка A».

GetTickCount переполняется каждые 49 дней, так что это способ в любом случае имеет врождённый потенциал к устраиванию проблем.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Mikle
Изобретатель велосипедов
Изобретатель велосипедов
Аватара пользователя
 
Сообщения: 4148
Зарегистрирован: 25.03.2003 (Вт) 14:02
Откуда: Туапсе

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Mikle » 18.11.2020 (Ср) 8:34

Хакер писал(а):GetTickCount переполняется каждые 49 дней, так что это способ в любом случае имеет врождённый потенциал к устраиванию проблем.

Разве это проблема? Просто отслеживаем случаи, когда счётчик на выходе меньше, чем на входе, и вносим поправку. Проблема возникнет только тогда, когда измеряемая величина может длиться больше 49 дней.

bon818
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 267
Зарегистрирован: 29.08.2009 (Сб) 4:49
Откуда: Ташкент

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение bon818 » 18.11.2020 (Ср) 15:43

Приглушите иронию. Мне удалось найти ее.
Вот она, легендарная точка "G" "B".
Не переживайте, что именно Я поставил последнею точку "Б" в этом топике.
Вам еще повезет.
А пока, насладитесь элегантностью кода:
Код: Выделить всё
Function GetTimeLoadWorktable() As Single
    Dim ti As NOTIFYICONDATA
    ti.cbSize = Len(ti)
    ti.uId = GetModuleHandle(ByVal 0)
    '--------
    While Shell_NotifyIcon(NIM_ADD, ti) = 0
        Sleep 1000
    Wend
    '--------
    Call Shell_NotifyIcon(NIM_DELETE, ti)
    GetTimeLoadWorktable = GetTickCount()
End Function

Описание функции:
-Получения уведомления о полной загрузке рабочего стола при старте системы.
-Способ измерения длительности загрузки операционной системы программным способом.

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

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Хакер » 18.11.2020 (Ср) 17:26

bon818 писал(а):Не переживайте, что именно Я поставил последнею точку "Б" в этом топике.

Каким образом этот код позволяет узнать время точки «Б», если код запустить через день после загрузки системы?
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

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

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Хакер » 18.11.2020 (Ср) 17:49

Mikle писал(а):Разве это проблема? Просто отслеживаем случаи, когда счётчик на выходе меньше, чем на входе, и вносим поправку.

У нас два счётчика, один из которых переполняется, а другой нет. Нужно вычислять разницу двух величин.

Конечно это проблема, если человеку об этом не сказать, а сам он о таком не догадывается.
—We separate their smiling faces from the rest of their body, Captain.
—That's right! We decapitate them.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 20.11.2020 (Пт) 8:03

Извините, скоро дам развернутый ответ, сейчас временно не могу.
bon818 - это то, что надо! :)

Teranas
Бывалый
Бывалый
Аватара пользователя
 
Сообщения: 224
Зарегистрирован: 13.12.2008 (Сб) 4:26
Откуда: Новосибирск

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Teranas » 20.11.2020 (Пт) 15:47

А я вот вообще не могу.
У каждой системы свой набор модулей и ещё этот набор зависит от настройки системы.
Допустим, узнаём какой модуль стартует первым в конкретной системе, а как понять когда весь этот кипишь закончится?
Ведь большинство модулей остаются в системе и продолжают работать.
Пожалуй соглашусь с Хакером.
С уважением, Андрей.

Vova_2581
Постоялец
Постоялец
 
Сообщения: 376
Зарегистрирован: 10.01.2010 (Вс) 18:08

Re: Как программно узнать, когда ОС полностью загрузилась

Сообщение Vova_2581 » 21.11.2020 (Сб) 15:07

С Хакером никто не спорит, при его опыте, профессионализме и знаниях он мог бы легко помогать людям, если бы хотел этого. А так... почитал я посты Хакера, и такая депрессия накатила, тоска, жизнь потеряла смысл. :cry: Несмотря на то, что на дворе уже почти зима, я открыл окно в своей квартире на первом этаже, встал босыми ногами на подоконник, в лицо дунул ледяной ветер с крупинками снега. В последний раз посмотрел на серое, холодное небо и подумал о вечном... В голове пронеслись самые яркие моменты жизни: первая любовь... школьные годы... институт... Говорят перед прыжком нельзя смотреть вниз... я старался именно так и делать. И вот, наступил решающий момент, последняя молитва, последний вздох... и(!)... ...(!) .... ... вдруг в моем кармане зажужжал телефон – пришло уведомление о новом сообщении на форуме – это был пост bon818. В это момент я заколебался... не выдержал... посмотрел вниз. Блин!.. высоко то как!! Потом в небо... снова вниз... на телефон... я не знал, как мне быть??? Мне как-то стало неуютно и холодно, думать о вечно уже не хотелось, да и высоты я боюсь. А в голове одна только мысль: какого хрена я делаю!!?? Я слез с подоконника, закрыл окно, одел свитер, закутался в плед, сел на диван и стал внимательно и с интересом читать пост от bon818. Это был шедевр! Очень необычный, я бы даже сказал, - оригинальное и нестандартное решение! И пусть даже что-то там с недостатками, - да по фиг! Супер! Мне снова захотелось жить и радоваться жизни, словно только что родился! Вот какие люди спасают, можно и так сказать, - жизнь своим оптимизмом! К чему я это... да к тому, что давно заметил, что посты Хакера хоть и правильные, грамотные, но пропитаны каким-то пессимизмом, типа: «да у вас все равно ничего не получится, лузеры!». Хакер не ищет путей к решению проблемы, Хакер ищет причину, для «...НЕ получится... лузеры! Это я вам гарантирую!». Вот в чем вся загвоздка. Так и жизнь теряет смысл, так и делать уже ничего не хочется. :cry: Нельзя же так! И только благодаря таким оптимистам как ALX_2002 и bon818 снова хочется творить и созидать. СПАСИБО Вам!!! :D

Не важно, зачем мне это надо, просто хотел в своей программе уведомлять пользователя в тот момент (или через промежуток времени), когда система будет полностью загружена, чтобы не мешать другим приложениям, службам и прочее. Думал, это просто решается и bon818 это подтвердил! Ну а дальше... тема стала развиваться сама по себе. Мне, в принципе, достаточно просто этого...
Код: Выделить всё
...
While Shell_NotifyIcon(NIM_ADD, ti) = 0
        Sleep 1000
Wend
msgbox «У нас все получилось, и мы не лузеры!»


Т.е. без уточнения времени, но противится развитию темы я не стал, наоборот... даже интересно стало. Код от bon818 дает +/– более точное время загрузки по сравнению с журналом... и это хорошо! bon818, СПАСИБО за код! :)

Хакер писал(а):Каким образом этот код позволяет узнать время точки «Б», если код запустить через день после загрузки системы?


Я позволил себе немного усовершенствовать код от bon818 добавив свойство запоминать дату и время запуска. Естественно этот код нужно скомпилировать в exe и запускать при старте системы в автозапуске(!). Тогда он покажет время в минутах и секундах и запомнит их, а при повторном запуске снова выдаст это время из памяти. Если запустить код в другой день, как писал Хакер «...через день...», то время пересчитается и снова запомнится. Так что все легко исправляется! :D

Код: Выделить всё
Private Declare Function Shell_NotifyIcon Lib "shell32.dll" Alias "Shell_NotifyIconA" (ByVal dwMessage As Long, lpData As NOTIFYICONDATA) As Long
Private Type NOTIFYICONDATA
        cbSize As Long
        hwnd As Long
        uID As Long
        uFlags As Long
        uCallbackMessage As Long
        hIcon As Long
        szTip As String * 64
End Type
Private Const NIM_ADD = &H0
Private Const NIM_DELETE = &H2
Private Declare Function GetModuleHandle Lib "kernel32" Alias "GetModuleHandleA" (ByVal lpModuleName As String) As Long
Private Declare Function GetTickCount Lib "kernel32" () As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Sub Form_Load()
On Error Resume Next
Dim strTime, strDate As String
Dim GetTime, TotalTime, FixTime, DrobnayaChast, SecTime As Long
strDate = GetSetting(App.Title, "DateLoad", "strDate", Default:=vbNullString)
 
  If Date <> CDate(strDate) Then
   GetTime = GetTimeLoadWorktable
   TotalTime = Format((GetTime / 1000 / 60), "##.##") 'Общее время
   FixTime = Fix(TotalTime) 'Целая часть
   DrobnayaChast = TotalTime - Int(TotalTime) 'Дробная часть
   'Вычисляем секунды от дробной части...
   SecTime = DrobnayaChast * 60
   MsgBox "Система загружается за: " & FixTime & " мин. и " & SecTime & " сек.", _
   vbInformation, "Время загрузки системы"
   SaveSetting App.Title, "TimeLoad", "strTime", GetTime
   SaveSetting App.Title, "DateLoad", "strDate", Date
  Else
   strTime = GetSetting(App.Title, "TimeLoad", "strTime", Default:="0")
   TotalTime = Format((strTime / 1000 / 60), "##.##")
   FixTime = Fix(TotalTime)
   DrobnayaChast = TotalTime - Int(TotalTime)
   SecTime = DrobnayaChast * 60
   MsgBox "Система загружается за: " & FixTime & " мин. и " & SecTime & " сек.", _
   vbInformation, "Время загрузки системы"
  End If
  End
End Sub

Function GetTimeLoadWorktable() As Single
    Dim ti As NOTIFYICONDATA
    ti.cbSize = Len(ti)
    ti.uID = GetModuleHandle(ByVal 0)
    '--------
    While Shell_NotifyIcon(NIM_ADD, ti) = 0
        Sleep 1000
    Wend
    '--------
    Call Shell_NotifyIcon(NIM_DELETE, ti)
    GetTimeLoadWorktable = GetTickCount()
End Function


Ну, что еще сказать... проблема решена! Спасибо всем участникам и отдельная благодарность bon818 и ALX_2002. Если бы не Вы, я бы прыгнул... ей Богу! :wink:
Тему можно считать закрытой!

P.S.
Хотел отдельно написать...
Когда декларировал Shell_NotifyIcon, использовал стандартную утилиту API Viewer из Add-Ins. Так вот, код все ни как не хотел работать и ругался на то, что в shell32.dll нет входа в Shell_NotifyIconA. Думал, что за фигня!!?? Ну не сам же я выдумал это объявление! Никак не мог понять, а потом случайно заметил, что псевдоним объявлен как « Shell_NotifyIconA» - то есть, с пробелом в начале! Когда я его убрал, то все заработало. Не думал, что в WIN32API.TXT есть такие ошибки. Вот так вот! Учитывайте!
Желаю творческих успехов! :D

След.

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

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

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

    TopList