Registrando-se para executar um programa
Você pode se registrar para que o BITS execute um programa com base em eventos de erro e transferência de trabalho, mas não em eventos modificados de trabalho. O BITS executa o programa no contexto do usuário.
Para se registrar para executar um programa
Chame o método IBackgroundCopyJob::QueryInterface para recuperar um ponteiro de interface IBackgroundCopyJob2 . Especifique __uuidof(IBackgroundCopyJob2) como o identificador de interface.
Chame o método IBackgroundCopyJob2::SetNotifyCmdLine para especificar o programa a ser executado e quaisquer argumentos exigidos pelo programa, como o identificador de trabalho.
Chame o método IBackgroundCopyJob::SetNotifyFlags para especificar quando a linha de comando será executada.
Você só pode especificar os sinalizadores de eventos BG_NOTIFY_JOB_TRANSFERRED e BG_NOTIFY_JOB_ERROR. O sinalizador BG_NOTIFY_JOB_MODIFICATION é ignorado.
Observe que o BITS não executará o programa se você também se registrou para receber retornos de chamada COM e o ponteiro da interface de retorno de chamada é válido ou o método de notificação que chama o BITS retorna um código de êxito. No entanto, se o método de notificação retornar um código de falha, como E_FAIL, o BITS executará a linha de comando.
O BITS chama a função CreateProcessAsUser para iniciar o programa. Se você especificar uma cadeia de caracteres de parâmetro, o primeiro parâmetro deverá ser o nome do programa.
O exemplo a seguir mostra como se registrar para executar um programa quando o evento job-transfer ocorre. O exemplo assume que o ponteiro da interface IBackgroundCopyJob é válido.
#define MAX_PARAMETER_LEN 4000
HRESULT hr;
IBackgroundCopyJob* pJob;
IBackgroundCopyJob2* pJob2 = NULL;
WCHAR szJobId[48];
const WCHAR *pProgram = L"c:\\PATHHERE\\PROGRAMNAMEHERE.exe";
WCHAR szParameters[MAX_PARAMETER_LEN+1];
GUID JobId;
int rc;
hr = pJob->GetId(&JobId);
if (SUCCEEDED(hr))
{
rc = StringFromGUID2(JobId, szJobId, ARRAYSIZE(szJobId));
if (rc)
{
StringCchPrintf(szParameters, MAX_PARAMETER_LEN+1, L"%s %s", pProgram, szJobId);
pJob->QueryInterface(__uuidof(IBackgroundCopyJob2), (void**)&pJob2);
hr = pJob2->SetNotifyCmdLine(pProgram, szParameters);
if (SUCCEEDED(hr))
{
hr = pJob->SetNotifyFlags(BG_NOTIFY_JOB_TRANSFERRED);
}
pJob2->Release();
if (FAILED(hr))
{
//Handle error - unable to register for command line notification.
}
}
}
Quando o estado do trabalho se torna BG_JOB_STATE_TRANSFERRED, o BITS executa o programa especificado em pProgram. O exemplo a seguir é uma implementação simples de um programa que usa um identificador de trabalho como um argumento. O programa assume que o número correto de argumentos é passado para ele.
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
#include <windows.h>
#include <bits.h>
#include <strsafe.h>
int wmain(int argc, wchar_t *argv[])
{
HRESULT hr;
IBackgroundCopyManager *pManager = NULL;
IBackgroundCopyJob *pJob = NULL;
GUID JobId;
LPWSTR pDisplayName = NULL;
LPCWSTR pSuccessString = L" completed successfully.";
LPWSTR pMessage;
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
hr = CoCreateInstance(__uuidof(BackgroundCopyManager),
NULL, CLSCTX_LOCAL_SERVER,
__uuidof(IBackgroundCopyManager), (void**)&pManager);
if (pManager)
{
hr = CLSIDFromString(argv[1], &JobId);
if (SUCCEEDED(hr))
{
hr = pManager->GetJob(JobId, &pJob);
if (SUCCEEDED(hr))
{
hr = pJob->GetDisplayName(&pDisplayName);
if (SUCCEEDED(hr))
{
int messageLen = wcslen(pDisplayName) + wcslen(pSuccessString) + 1;
pMessage = (WCHAR*)malloc(messageLen * sizeof(WCHAR));
if (pMessage)
{
StringCchPrintf(pMessage, messageLen,
L"%s%s", pDisplayName, pSuccessString);
MessageBox(HWND_DESKTOP, pMessage, L"MyProgram - Transferred", MB_OK);
free(pMessage);
}
else
{
hr = E_OUTOFMEMORY;
}
CoTaskMemFree(pDisplayName);
}
pJob->Release();
}
}
pManager->Release();
}
CoUninitialize();
return(hr);
}