Controle um download do BITS em uma conexão cara
Este tópico mostra como bloquear o download de um trabalho do BITS em uma conexão cara, como um link de celular móvel. O BITS é uma API assíncrona em que o aplicativo cria um trabalho, adiciona URLs a esse trabalho e chama a função Resume do objeto de trabalho. A partir desse ponto, o BITS escolhe quando o trabalho é baixado com base em fatores como a prioridade do trabalho e a política de transferência. Depois que o download do trabalho for concluído, o BITS notificará o aplicativo de que a URL foi baixada (se o aplicativo tiver se registrado para notificação de conclusão). Durante a vida útil do trabalho, se a rede do usuário final mudar, como se o usuário estiver viajando e estiver incorrendo em taxas de roaming, o BITS suspenderá o trabalho até que as condições de rede sejam ideais. As instruções passo a passo a seguir mostram como criar o trabalho e especificar as configurações de diretiva de transferência apropriadas.
Pré-requisitos
- Microsoft Visual Studio
Instruções
Etapa 1: Incluir os arquivos de cabeçalho BITS necessários
Insira as seguintes diretivas de cabeçalho na parte superior do arquivo de origem.
#include <bits.h>
#include <bits5_0.h>
Etapa 2: Inicializar COM
Antes de instanciar a interface IBackgroundCopyManager (usada para criar um trabalho do BITS), você deve inicializar COM, definir o modelo de threading COM e especificar um nível de representação de pelo menos RPC_C_IMP_LEVEL_IMPERSONATE.
// 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))
{
...
Etapa 3: Instanciar a interface IBackgroundCopyManager
Use a interface IBackgroundCopyManager para criar trabalhos de transferência, recuperar um objeto enumerador que contém os trabalhos na fila e recuperar trabalhos individuais da fila.
IBackgroundCopyManager* pQueueMgr;
hr = CoCreateInstance(__uuidof(BackgroundCopyManager),
NULL,
CLSCTX_LOCAL_SERVER,
__uuidof(IBackgroundCopyManager),
(void **)&pQueueMgr);
Etapa 4: Criar o trabalho do BITS
Somente o usuário que cria o trabalho ou um usuário com privilégios de administrador pode adicionar arquivos ao trabalho e alterar as propriedades do trabalho.
GUID guidJob;
IBackgroundCopyJob* pBackgroundCopyJob;
hr = pQueueMgr->CreateJob(L"TransferPolicy",
BG_JOB_TYPE_DOWNLOAD,
&guidJob,
(IBackgroundCopyJob **)&pBackgroundCopyJob);
Etapa 5: Especificar a configuração de diretiva de transferência para o trabalho
É aqui que você especifica a política de transferência de estado de custo. Você pode definir vários sinalizadores de BITS_COST_STATE usando uma combinação bit a bit OU para obter os resultados desejados.
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);
}
Exemplo
O exemplo de código a seguir mostra como definir a política de transferência de um trabalho do BITS para que o processamento do trabalho não ocorra enquanto determinadas condições são atendidas, como quando o usuário está em roaming ou excedeu seu limite mensal de transferência de dados.
//*********************************************************
//
// 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;
}