プログラム実行の登録

BITS でジョブ転送イベントとエラー イベントに基づいてプログラムを実行するように登録できますが、ジョブが変更されたイベントは実行できません。 BITS は、ユーザーのコンテキストでプログラムを実行します。

プログラム実行を登録するには

  1. IBackgroundCopyJob::QueryInterface メソッドを呼び出して、IBackgroundCopyJob2 インターフェイス ポインターを取得します。 インターフェイス識別子として __uuidof(IBackgroundCopyJob2) を指定します。

  2. IBackgroundCopyJob2::SetNotifyCmdLine メソッドを呼び出して、実行するプログラムと、プログラムで必要な引数 (ジョブ識別子など) を指定します。

  3. 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);
}