エラー処理 (BITS)
アプリケーションで処理するエラーは 2 種類あります。 最初のエラーはメソッド呼び出しの失敗です。 各メソッドは HRESULT 値を返します。 各メソッドのリファレンス ページには、生成される可能性が最も高い戻り値が記載されています。 その他の戻り値については、「BITS 戻り値」を参照してください。 戻り値に関連付けられているメッセージ テキストを取得するには、IBackgroundCopyManager::GetErrorDescription メソッドを呼び出します。
処理する 2 番目の種類のエラーは、状態が BG_JOB_STATE_ERROR または BG_JOB_STATE_TRANSIENT_ERROR に遷移するジョブです。 これらの種類のエラーに関連する情報を取得するには、ジョブの IBackgroundCopyJob::GetError メソッドを呼び出します。 このメソッドは、エラーの原因を特定するために使用する情報を含む IBackgroundCopyError インターフェイス ポインターを返します。 イベント通知を受信するように登録することで、エラー通知を受け取ることもできます。 詳細については、「COM コールバックの登録」を参照してください。
BITS は、各ジョブをアトミックと見なします。 ジョブ内のファイルの 1 つでエラーが発生した場合、エラーが解決されるまでジョブはエラー状態のままになります。 したがって、ジョブからエラーの原因となっているファイルを削除することはできません。 ただし、サーバーが使用できないか、無効なリモート ファイルが原因でエラーが発生した場合はIBackgroundCopyJob3::ReplaceRemotePrefix メソッドまたは IBackgroundCopyFile2::SetRemoteName メソッドを呼び出して、新しいサーバーまたはファイル名を識別できます。
エラーの原因を特定したら、次のいずれかのオプションを実行します。
- IBackgroundCopyJob::Cancel メソッドを呼び出してジョブを取り消します。
- ダウンロード ジョブの場合は、IBackgroundCopyJob::Complete メソッドを呼び出して、エラーが発生する前に正常に転送されたファイルを保存します。
- エラーを修正し、IBackgroundCopyJob::Resume メソッドを呼び出してジョブを完了します。
アップロード/応答ジョブの場合は、BG_JOB_REPLY_PROGRESS 構造体の BytesTotal メンバーの値をチェックして、ジョブのアップロード部分または応答部分でエラーが発生したかどうかを判断します。 値が BG_SIZE_UNKNOWN の場合、アップロード時にエラーが発生しています。
次の例は、IBackgroundCopyError インターフェイス ポインターを取得する方法を示しています。 この例では、IBackgroundCopyJob インターフェイス ポインターが有効であると想定しています。
HRESULT hr = 0;
HRESULT hrError = 0;
IBackgroundCopyJob* pJob;
IBackgroundCopyError* pError = NULL;
IBackgroundCopyFile* pFile = NULL;
WCHAR* pszDescription = NULL;
WCHAR* pszRemoteName = NULL;
BG_ERROR_CONTEXT Context;
hr = pJob->GetError(&pError);
if (SUCCEEDED(hr))
{
//Retrieve the HRESULT associated with the error. The context tells you
//where the error occurred, for example, in the transport, queue manager, the
//local file, or the remote file.
pError->GetError(&Context, &hrError);
//Retrieve a description associated with the HRESULT value.
hr = pError->GetErrorDescription(LANGIDFROMLCID(GetThreadLocale()), &pszDescription);
if (SUCCEEDED(hr))
{
if (BG_ERROR_CONTEXT_REMOTE_FILE == Context)
{
hr = pError->GetFile(&pFile);
if (SUCCEEDED(hr))
{
hr = pFile->GetRemoteName(&pszRemoteName);
if (SUCCEEDED(hr))
{
//Do something with the information.
CoTaskMemFree(pszRemoteName);
}
pFile->Release();
}
}
CoTaskMemFree(pszDescription);
}
pError->Release();
}
else
{
//Error information is not available.
}