proxy - Hvorfor er ikke IUpdateSession :: WebProxy arbejder på Windows 10?

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har fået en intern kode, der udfører en Microsoft Update-scanning ved hjælp af Windows Update API. Fordi nogle af klienterne ikke har direkte internetadgang, sætter jeg eksplicit WebProxy -egenskaben til pege på vores lokale proxyserver Under testningen (på Windows 7) syntes dette at fungere perfekt. Nu tester jeg det på Windows 10 (se fodnote 1), og det ser ud til, at proxyindstillingen ignoreres.


Windows Update-klienten blev revideret væsentligt i Windows 10, så det er muligt , at dette er en fejl eller ubegrænset begrænsning i den nye version af klienten, men på den anden side Jeg har lidt tidligere erfaring ved hjælp af COM, så jeg kan gøre noget forkert.


Observerede resultater ved hjælp af testkoden, der er angivet nedenfor:



  • Koden fungerer som ønsket i Windows 7, uanset hvilken sikkerhedskontekst den køres i, og uanset om klienten har direkte internetadgang og/eller en proxyserver konfigureret i brugerens internetindstillinger.

  • Koden virker også på Windows 10, forudsat at klienten har direkte internetadgang.

  • Koden for det meste virker på Windows 10, hvis klienten ikke har direkte internetadgang, men den bruger, der kører den, har en passende proxyserver konfigureret i deres internetindstillinger. (Se fodnote 2.)

  • Koden ikke fungerer på Windows 10, hvis klienten ikke har direkte internetadgang, og den bruger, der kører den, har ikke en passende proxy konfigureret. I stedet for at forbinde til den proxy, der er angivet i koden, forsøger den at oprette forbindelse til en række eksterne IP-adresser; Når alle disse forbindelsesforsøg endelig er udløbet, returnerer den 0x80072ee2, ERROR\_INTERNET\_TIMEOUT, på den viste linje. (Jeg kan få meget lignende adfærd på Windows 7 ved at udelade den del af koden, der angiver proxyserveren.)



Hvis jeg med vilje ændrer proxy-webadressen i koden for at pege på en ikke-eksisterende server, stopper koden med at arbejde på Windows 7 som forventet, men adfærd på Windows 10 er uændret. Så det ser virkelig ud som om Windows Update simpelthen ignorerer ejendommen WebProxy. (Ejendommen er sat, jeg kan læse den tilbage fra objektet IUpdateSession.


Ændring af leveringsoptimering Hentningstilstanden ser ikke ud til at hjælpe. Jeg har prøvet alle de forskellige tilstande, der er tilgængelige via Gruppepolitik. Tilføjelse af et efterfølgende skråstreg til proxy-webadressen ødelagde koden til Windows 7 og gjorde ingen forskel for Windows 10. Brug et blott DNS-navn i stedet for en webadresse fungeret på Windows 7 men gjorde ingen forskel på Windows 10.


Da koden i sidste ende er beregnet til at blive en del af en systemtjeneste og/eller køres eksternt, er konfiguration af proxyindstillinger på brugerniveau ikke en ideel løsning, selvom jeg måske kan falde tilbage på det, hvis der ikke findes nogen anden løsning.


Dette er koden jeg har testet, en nedskaleret version af den originale kode. Testkoden behandler faktisk ikke resultaterne, hvis der er noget, da problemet opstår før dette punkt. Jeg har gemt det rigtige DNS-navn på vores proxyserver, men URL'en er af den viste formular. Enhver, der vil teste koden i deres eget miljø, vil selvfølgelig nødt til at pege på det i deres egen proxy.


#include <windows.h>
#include <wuapi.h>

#include <stdio.h>

#define stringize1(x) L#x
#define stringize(x) stringize1(x)

#define fail() fail\_fn(L"Fatal error at line " stringize(\_\_LINE\_\_))

void fail\_fn(wchar\_t * msg)
{
    wprintf(L"\%s
", msg);
    exit(1);
}

int wmain(int argc, wchar\_t ** argv)
{
    IUpdateSearcher* updateSearcher;
    IWebProxy* webProxy;
    IUpdateServiceManager2* serviceManager;
    IUpdateServiceRegistration* serviceRegistration;
    IUpdateSession* updateSession;
    ISearchResult* results;
    BSTR searchString, proxyString, bstrServiceID;

    HRESULT hr;

    if((hr = CoInitialize(NULL)) != S\_OK) {
        fail();
    }

    hr = CoCreateInstance(&CLSID\_UpdateServiceManager, NULL, CLSCTX\_INPROC\_SERVER, 
                          &IID\_IUpdateServiceManager2, (void **)&serviceManager);
    if (hr != S\_OK) fail();

    bstrServiceID = SysAllocString(L"7971f918-a847-4430-9279-4a52d1efe18d");

    serviceManager->lpVtbl->AddService2(serviceManager, bstrServiceID, 
                  asfAllowPendingRegistration | asfRegisterServiceWithAU, 
                  NULL, &serviceRegistration);
    if (hr != S\_OK) fail();

    hr = CoCreateInstance(&CLSID\_UpdateSession, NULL, CLSCTX\_INPROC\_SERVER,
                          &IID\_IUpdateSession, (LPVOID*)&updateSession);
    if (hr != S\_OK) fail();

    hr = CoCreateInstance(&CLSID\_WebProxy, NULL, CLSCTX\_INPROC\_SERVER,
                           &IID\_IWebProxy, (void **)&webProxy);
    if (hr != S\_OK) fail();

    hr = webProxy->lpVtbl->put\_AutoDetect(webProxy, VARIANT\_FALSE);
    if (hr != S\_OK) fail();

    proxyString = SysAllocString(L"http://proxy.contoso.co.nz:80");
    if (proxyString == NULL) fail();

    hr = webProxy->lpVtbl->put\_Address(webProxy, proxyString);
    if (hr != S\_OK) fail();

    hr = updateSession->lpVtbl->put\_WebProxy(updateSession, webProxy);
    if (hr != S\_OK) fail();

    hr = updateSession->lpVtbl->CreateUpdateSearcher(updateSession, &updateSearcher);
    if (hr != S\_OK) fail();

    hr = updateSearcher->lpVtbl->put\_ServerSelection(updateSearcher, ssOthers);
    if (hr != S\_OK) fail();

    hr = updateSearcher->lpVtbl->put\_ServiceID(updateSearcher, bstrServiceID);
    if (hr != S\_OK) fail();

    searchString = SysAllocString(L"IsInstalled=0 and Type='Software'");
    hr = updateSearcher->lpVtbl->Search(updateSearcher, searchString, &results);
    if (hr != S\_OK)  /* fails here */
    {
        wprintf(L"Error \%0x
", hr);
        fail();
    }

    wprintf(L"Update search completed successfully.
");

    CoUninitialize();
    exit(0);
}


Er der noget, jeg kan gøre for at gøre dette arbejde på Windows 10 på samme måde som det gør på Windows 7?





(1) Jeg kører Windows 10 LTSB 2016. Dette er stort set den samme som Windows 10 version 1607, også kendt som Windows 10 Anniversary Update. De fleste af mine klienter har ikke opdateringerne i marts, men er ellers opdaterede. Jeg har også bekræftet, at problemet stadig opstår på en klient med installerede marts-opdateringer.


(2) Under testningen har brugen af ​​den brugerkonfigurerede proxy mistet ved to lejligheder, både på nyinstallerede maskiner; Når den begynder at virke, fortsætter den med at fungere. I dette scenario forsøger scanningen stadig at oprette forbindelse til forskellige eksterne IP-adresser, men det forhold, at disse forbindelser går ud, forårsager ikke, at scanningen mislykkes. Jeg har mistanke om alt dette har noget at gøre med downloadoptimering af leveringsoptimering, men jeg eksperimenterer stadig.





Addendum: Det tilfælde, hvor brugerkontoen koden kører som har en passende proxyserver konfigureret i deres internetindstillinger, virker kun, når koden køres interaktivt. I en ikke-interaktiv sammenhæng, f.eks. En tjeneste eller en planlagt opgave, virker dette ikke . På nuværende tidspunkt synes det mig umuligt på en Windows 10-maskine at få adgang til Microsoft Update fra en tjeneste, medmindre du har direkte internetadgang.

Bedste reference