Registro para ejecutar un programa
Puede registrarse para que BITS ejecute un programa en función de los eventos de error y transferidos del trabajo, pero no los eventos modificados por el trabajo. BITS ejecuta el programa en el contexto del usuario.
Para registrarse para ejecutar un programa
Llame al método IBackgroundCopyJob::QueryInterface para recuperar un puntero de interfaz IBackgroundCopyJob2 . Especifique __uuidof(IBackgroundCopyJob2) como identificador de interfaz.
Llame al método IBackgroundCopyJob2::SetNotifyCmdLine para especificar el programa que se va a ejecutar y los argumentos requeridos por el programa, como el identificador del trabajo.
Llame al método IBackgroundCopyJob::SetNotifyFlags para especificar cuándo se ejecuta la línea de comandos.
Solo puede especificar las marcas de evento BG_NOTIFY_JOB_TRANSFERRED y BG_NOTIFY_JOB_ERROR. Se omite la marca BG_NOTIFY_JOB_MODIFICATION.
Tenga en cuenta que BITS no ejecutará el programa si también registró para recibir devoluciones de llamada COM y el puntero de la interfaz de devolución de llamada es válido o el método de notificación que BITS llama devuelve un código correcto. Sin embargo, si el método de notificación devuelve un código de error, como E_FAIL, BITS ejecutará la línea de comandos.
BITS llama a la función CreateProcessAsUser para iniciar el programa. Si especifica una cadena de parámetro, el primer parámetro debe ser el nombre del programa.
En el ejemplo siguiente se muestra cómo registrarse para ejecutar un programa cuando se produce el evento transferido por el trabajo. En el ejemplo se supone que el puntero de interfaz IBackgroundCopyJob es 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.
}
}
}
Cuando el estado del trabajo se convierte en BG_JOB_STATE_TRANSFERRED, BITS ejecuta el programa especificado en pProgram. El ejemplo siguiente es una implementación sencilla de un programa que toma un identificador de trabajo como argumento. El programa supone que se le pasa el número correcto de argumentos.
#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);
}