Share via


Steuern eines BITS-Downloads über eine teure Verbindung

In diesem Thema wird gezeigt, wie Sie das Herunterladen eines BITS-Auftrags über eine teure Verbindung wie eine Roamingverbindung blockieren. BITS ist eine asynchrone API, bei der die Anwendung einen Auftrag erstellt, urLs zu diesem Auftrag hinzufügt und die Resume-Funktion des Auftragsobjekts aufruft. Ab diesem Punkt wählt BITS basierend auf Faktoren wie Auftragspriorität und Übertragungsrichtlinie aus, wann der Auftrag heruntergeladen wird. Nachdem der Download des Auftrags abgeschlossen ist, benachrichtigt BITS die Anwendung darüber, dass die URL heruntergeladen wurde (wenn die Anwendung zur Abschlussbenachrichtigung registriert wurde). Wenn sich das Netzwerk des Endbenutzers während der Lebensdauer des Auftrags ändert , z. B. wenn der Benutzer unterwegs ist und derzeit Roaminggebühren anfallen, wird der Auftrag von BITS angehalten, bis die Netzwerkbedingungen optimal sind. Die folgenden schrittweisen Anweisungen zeigen, wie Sie den Auftrag erstellen und die entsprechenden Übertragungsrichtlinieneinstellungen angeben.

Voraussetzungen

  • Microsoft Visual Studio

Anweisungen

Schritt 1: Einschließen der erforderlichen BITS-Headerdateien

Fügen Sie die folgenden Headerdirektiven am Anfang der Quelldatei ein.

#include <bits.h>
#include <bits5_0.h>

Schritt 2: Initialisieren von COM

Vor dem Instanziieren der IBackgroundCopyManager-Schnittstelle (zum Erstellen eines BITS-Auftrags) müssen Sie COM initialisieren, das COM-Threadingmodell festlegen und eine Identitätswechselebene von mindestens RPC_C_IMP_LEVEL_IMPERSONATE angeben.

// Initialize COM and specify the COM threading model.
HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr))
{
 // Specify an impersonation level of at least RPC_C_IMP_LEVEL_IMPERSONATE.
 hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
                           RPC_C_AUTHN_LEVEL_CONNECT,
                           RPC_C_IMP_LEVEL_IMPERSONATE,
                           NULL, EOAC_NONE, 0);
 if (SUCCEEDED(hr))
 {
  ...

Schritt 3: Instanziieren der IBackgroundCopyManager-Schnittstelle

Verwenden Sie die IBackgroundCopyManager-Schnittstelle , um Übertragungsaufträge zu erstellen, ein Enumeratorobjekt abzurufen, das die Aufträge in der Warteschlange enthält, und einzelne Aufträge aus der Warteschlange abzurufen.

IBackgroundCopyManager* pQueueMgr;

hr = CoCreateInstance(__uuidof(BackgroundCopyManager),
                      NULL,
                      CLSCTX_LOCAL_SERVER,
                      __uuidof(IBackgroundCopyManager),
                      (void **)&pQueueMgr);

Schritt 4: Erstellen des BITS-Auftrags

Nur der Benutzer, der den Auftrag erstellt, oder ein Benutzer mit Administratorrechten kann dem Auftrag Dateien hinzufügen und die Eigenschaften des Auftrags ändern.

GUID guidJob;
IBackgroundCopyJob* pBackgroundCopyJob;

hr = pQueueMgr->CreateJob(L"TransferPolicy",
                          BG_JOB_TYPE_DOWNLOAD,
                          &guidJob,
                          (IBackgroundCopyJob **)&pBackgroundCopyJob);

Schritt 5: Angeben der Übertragungsrichtlinieneinstellung für den Auftrag

Hier geben Sie die Richtlinie für die Kostenzustandsübertragung an. Sie können mehrere BITS_COST_STATE-Flags festlegen, indem Sie eine bitweise OR-Kombination verwenden, um die gewünschten Ergebnisse zu erzielen.

BITS_JOB_PROPERTY_VALUE propval;
IBackgroundCopyJob5* pBackgroundCopyJob5;

propval.Dword = BITS_COST_STATE_USAGE_BASED
              | BITS_COST_STATE_OVERCAP_THROTTLED
              | BITS_COST_STATE_BELOW_CAP
              | BITS_COST_STATE_CAPPED_USAGE_UNKNOWN
              | BITS_COST_STATE_UNRESTRICTED;

hr = pBackgroundCopyJob->QueryInterface(__uuidof(IBackgroundCopyJob5),
                                        reinterpret_cast<void**>(&pBackgroundCopyJob5));
if(SUCCEEDED(hr))
{
 pBackgroundCopyJob5->SetProperty(BITS_JOB_PROPERTY_ID_COST_FLAGS, propval);
}

Beispiel

Das folgende Codebeispiel zeigt, wie die Übertragungsrichtlinie eines BITS-Auftrags so festgelegt wird, dass die Verarbeitung des Auftrags nicht erfolgt, während bestimmte Bedingungen erfüllt sind, z. B. wenn der Benutzer roamingt oder sein monatliches Datenübertragungslimit überschritten hat.

//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Microsoft Public License.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

#define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <bits.h>
#include <stdio.h> // define wprintf


int main()
{
 HRESULT hr = S_OK;
 GUID guidJob;
 IBackgroundCopyJob5* pBackgroundCopyJob5;  
 IBackgroundCopyJob* pBackgroundCopyJob;
 IBackgroundCopyManager* pQueueMgr;
 BITS_JOB_PROPERTY_VALUE propval;

 // Specify the COM threading model.
 hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
 if (SUCCEEDED(hr))
 {
  // The impersonation level must be at least RPC_C_IMP_LEVEL_IMPERSONATE.
  hr = CoInitializeSecurity(NULL, -1, NULL, NULL,
                            RPC_C_AUTHN_LEVEL_CONNECT,
                            RPC_C_IMP_LEVEL_IMPERSONATE,
                            NULL, EOAC_NONE, 0);

  if (SUCCEEDED(hr))
  {
   hr = CoCreateInstance(__uuidof(BackgroundCopyManager), 
                         NULL,
                         CLSCTX_LOCAL_SERVER,
                         __uuidof(IBackgroundCopyManager),
                         (void **)&pQueueMgr);

   if (FAILED(hr))
   {
    // Failed to connect to BITS.
    wprintf(L"Failed to connect to BITS with error %x\n",hr);
    goto done;
   }

   // Create a BITS job.
   wprintf(L"Creating Job...\n");

   hr = pQueueMgr->CreateJob(L"TransferPolicy",
                             BG_JOB_TYPE_DOWNLOAD,
                             &guidJob,
                             (IBackgroundCopyJob **)&pBackgroundCopyJob);

   if (FAILED(hr))
   {
    wprintf(L"Failed to Create Job, error = %x\n",hr);
    goto cancel;
   }

   wprintf(L" Job is succesfully created ...\n");

   // Set the Transfer Policy for the job.
   propval.Dword = BITS_COST_STATE_USAGE_BASED 
                 | BITS_COST_STATE_OVERCAP_THROTTLED
                 | BITS_COST_STATE_BELOW_CAP
                 | BITS_COST_STATE_CAPPED_USAGE_UNKNOWN
                 | BITS_COST_STATE_UNRESTRICTED;

   hr = pBackgroundCopyJob->QueryInterface(
         __uuidof(IBackgroundCopyJob5),
         reinterpret_cast<void**>(&pBackgroundCopyJob5)
        );

   if (FAILED(hr))
   {
    wprintf(L"Failed to Create Job, error = %x\n",hr);
    goto cancel;
   }
   pBackgroundCopyJob5->SetProperty(BITS_JOB_PROPERTY_ID_COST_FLAGS, propval);

   // Get the Transfer Policy for the new job.
   BITS_JOB_PROPERTY_VALUE actual_propval;

   wprintf(L"Getting TransferPolicy Property ...\n");

   hr = pBackgroundCopyJob5->GetProperty(BITS_JOB_PROPERTY_ID_COST_FLAGS, 
                                         &actual_propval);
   if (FAILED(hr))
   {
    // SetSSLSecurityFlags failed.
    wprintf(L"GetProperty failed with error %x\n",hr);
    goto cancel;
   }

   DWORD job_transferpolicy = actual_propval.Dword;
   wprintf(L"get TransferPolicy Property returned %#x\n", job_transferpolicy);
  }
done:
  CoUninitialize();
 }
 return 1;

cancel:
 pBackgroundCopyJob->Cancel(); 
 pBackgroundCopyJob->Release();
 goto done;
}