Windows Update API с C# не находит установленных обновлений

У меня есть несколько ПК с Windows 7, для которых нужно установить исправления с определенным обновлением Windows, используя API-интерфейс Windows Update в консольном приложении C#. API должен найти установленные обновления и сообщить, если он уже установлен, и выполнить установку, если нет.

Во время тестирования на виртуальном ПК (клиент Windows 7 Professional Hyper-v) у меня возникла ситуация, аналогичная целевым ПК (Windows 7 Embedded), когда следующий код возвращает (очень быстро и без каких-либо исключений) 0 обновлений. Что я знаю, что неправильно. Фактически, это даже возвращает это после того, как я устанавливаю обновление MSU.

Код:

 UpdateSession uSession = new UpdateSession();
 IUpdateSearcher uSearcher = uSession.CreateUpdateSearcher();
 uSearcher.Online = false;
 try
 {
    ISearchResult sResult = uSearcher.Search("IsInstalled=1 And IsHidden=0");
    Console.WriteLine("Found " + sResult.Updates.Count + " updates");
    foreach (IUpdate update in sResult.Updates)
    {
       Console.WriteLine(update.Title);
       if (update.Title.ToLower().Contains("kb123456")) {
        //Update is not required
        ReportInstalled();
        return;
       }
     }
     //If we get here, the update is not installed
     InstallUpdate();
  }
  catch (Exception ex)
  {
    Console.WriteLine("Something went wrong: " + ex.Message);
  }

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

Похоже, что процесс поиска обновлений вручную запускает / перезапускает некоторые службы и / или другие процессы, однако я изо всех сил пытаюсь точно выяснить, что мне нужно сделать с системой, чтобы привести ее в правильное состояние. Я ожидаю, что ответом будет простой случай запуска службы x или процесса y с набором аргументов, но какой?

Некоторые (не все) вещи, которые я пробовал, но не изменили поведение:

  1. Запустил службу BITS, перезапустил службу Windows Update
  2. Пробовал запуск wuauclt.exe с различными ключами (задокументировано здесь в комментариях)

Когда компьютер находится в состоянии, когда код работает правильно (после того, как я запустил WU вручную), я заметил, что процесс wuauclt.exe запускается при запуске приведенного выше кода. Когда он находится в целевом состоянии (до запуска WU вручную), wuauclt.exe не запускается, и я не могу запустить его вручную, я подозреваю, что это большая подсказка.

Еще одна подсказка - это состояние Центра обновления Windows, прежде чем я запускаю его вручную. В панели управления окнами обновление выглядит так:

После запуска WU и установки обновлений с помощью этого метода, и компьютер находится в состоянии, когда код работает так, как ожидалось, WU выглядит следующим образом:

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

0 ответов

Поскольку на этот вопрос в настоящий момент нет ответа (хотя объединенные комментарии в основном дают ответ), вот что здесь произошло:

Это очень распространенный подход к проверке "Есть ли у меня исправления, необходимые для успешной работы моей программы?", И он имеет краткосрочную и долгосрочную проблему.

Краткосрочная проблема:

Код поиска выполняет автономное сканирование (он устанавливает для IUpdateSearcher::Online значение false). Это обычная тактика для ускорения поиска. Проблема в том, что он обрабатывает только те обновления, которые были доступны во время предыдущего онлайн-сканирования. Если компьютер давно не выполнял онлайн-сканирование, результаты будут устаревшими. Если после последнего онлайн-сканирования на компьютере произошли заметные изменения аппаратного или программного обеспечения, то результаты будут неполными. Если компьютер никогда не выполнял онлайн-сканирование, то IUpdateSearcher::Search не будет возвращать ошибку - он просто немедленно сообщит, что обновления не применимы.

Поэтому, если вы хотите ускорить процесс, выполнив автономное сканирование, рекомендуется проверить IAutomaticResults::LastSearchSuccessDate, который сообщает вам, когда в последний раз автоматические обновления выполняли сканирование. Поскольку сканирование с автоматическим обновлением выполняется онлайн, вы знаете, что в это время было выполнено онлайн-сканирование. Если дате более нескольких дней, вам следует выполнить онлайн-сканирование.

Долгосрочная проблема:

Этот код предполагает, что обновление KB123456 существует и актуально для компьютера. Но это, по сути, ограниченное по времени предположение, и этот срок в наши дни часто довольно короткий. Если исправления в KB123456 будут добавлены в новое накопительное обновление KB234567, то в какой-то момент KB123456 может быть истек из Центра обновления Windows. В этот момент ваш поиск всегда будет возвращать "не установлен", даже если исправленный код действительно находится на ПК.

Вместо того, чтобы проверять "Установлен ли KB X?", Лучше проверить "Установлено ли исправление / компонент, который мне нужно?"

  • Если возможно, проверьте исправление / функцию напрямую. Например, если вам нужен конкретный новый Windows API, вы можете использовать Наборы API, если ОС поддерживает его, или просто использовать LoadLibrary и GetProcAddress, чтобы узнать, содержит ли библиотека DLL нужную вам функцию.

  • Если тестирование непосредственно на исправление / функцию невозможно, проверьте состояние самой Windows, чтобы убедиться, что это то, что вам нужно. В Windows 10 вам часто нужно просто проверить номер сборки. В более старых версиях ОС вместо жесткого кодирования номера базы знаний вы можете просмотреть примечания к исправлению для базы знаний, узнать, какие библиотеки DLL обновляются и до каких номеров версий они обновляются, а затем использовать эти имена и версии DLL для своей среды выполнения. проверить.

  • В зависимости от того, что именно вы тестируете, и от контекста, в котором вы выполняете тест (создание сценариев и т. Д.), Команда DISM также может быть полезной - если вам нужен конкретный пакет Windows, вы можете использовать DISM /ONLINE /GET-PACKAGES и посмотрите, отображается ли ваш пакет в выводе.

Другие вопросы по тегам