注册以执行程序
可以注册以使 BITS 根据作业传输和错误事件执行程序,但不能根据作业修改事件执行程序。 BITS 在用户的上下文中执行程序。
注册以执行程序
调用 IBackgroundCopyJob::QueryInterface 方法以检索 IBackgroundCopyJob2 接口指针。 指定 __uuidof(IBackgroundCopyJob2) 作为接口标识符。
调用 IBackgroundCopyJob2::SetNotifyCmdLine 方法以指定要执行的程序以及程序所需的任何参数,例如作业标识符。
调用 IBackgroundCopyJob::SetNotifyFlags 方法以指定命令行何时执行。
只能指定 BG_NOTIFY_JOB_TRANSFERRED 和 BG_NOTIFY_JOB_ERROR 事件标志。 BG_NOTIFY_JOB_MODIFICATION 标志将被忽略。
请注意,如果还注册以接收 COM 回调且回调接口指针有效,或者 BITS 调用的通知方法返回成功代码,则 BITS 不会执行程序。 但是,如果通知方法返回失败代码(如 E_FAIL),则 BITS 将执行命令行。
BITS 调用 CreateProcessAsUser 函数来启动程序。 如果指定参数字符串,则第一个参数必须是程序名称。
以下示例显示了在发生作业传输事件时如何注册以执行程序。 该示例假定 IBackgroundCopyJob 接口指针有效。
#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.
}
}
}
当作业的状态变为 BG_JOB_STATE_TRANSFERRED 时,BITS 将执行 pProgram 中指定的程序。 以下示例是一个以作业标识符作为参数的程序的简单实现。 程序假定传递给它的参数数量正确。
#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);
}