IBackgroundCopyFile2
COM公式ドキュメント
IBackgroundCopyFile2 インターフェイスを使用すると、ファイルに新しいリモート名を指定したり、ダウンロードする範囲の一覧を取得したりできます。
メソッド 2
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
リモートファイルからダウンロードする範囲を取得します。
| RangeCount | DWORD* | inout | Ranges 内の要素数。 |
| Ranges | BG_FILE_RANGE** | out | ダウンロードする範囲を指定する BG_FILE_RANGE 構造体の配列。使用が終わったら、CoTaskMemFree 関数を呼び出して Ranges を解放します。 |
戻り値
このメソッドは、次の戻り値のほか、その他の値を返します。
| 戻り値 | 説明 |
|---|---|
| 成功 | |
| 範囲が指定されていないか、ジョブがアップロードジョブまたはアップロード応答ジョブです。RangeCount は 0 に設定され、Ranges は NULL に設定されます。 |
ダウンロードジョブ内のリモート名を新しい URL に変更します。
| Val | LPWSTR | in | サーバー上のファイル名を含む、NULL で終わる文字列。リモート名の指定方法については、BG_FILE_INFO 構造体の RemoteName メンバーおよび「解説」セクションを参照してください。 |
戻り値
このメソッドは、次の戻り値のほか、その他の値を返します。
| 戻り値 | 説明 |
|---|---|
| 成功 | |
| 新しいリモート名が無効な URL であるか、新しい URL が長すぎます (URL は 2,200 文字を超えることはできません)。 | |
| アップロードジョブまたはアップロード応答ジョブに対してこのメソッドを呼び出すことはできません。このメソッドはダウンロードジョブに対してのみ呼び出してください。 | |
| ジョブの状態が BG_JOB_STATE_CANCELLED または BG_JOB_STATE_ACKNOWLEDGED であってはなりません。 |
解説(Remarks)
通常、このメソッドは、ファイルの転送に使用するプロトコルを変更する場合 (たとえば SMB から HTTP へ) や、ファイル名またはパスを変更する場合に呼び出します。
このメソッドは、戻り時にシリアル化を行いません。変更をシリアル化するには、ジョブを中断 (Suspend) し、このメソッドを呼び出して (ジョブ内の複数のファイルを変更する場合はループを使用します)、ジョブを再開 (Resume) します。IBackgroundCopyJob::Resume メソッドを呼び出すと、変更がシリアル化されます。
新しいリモート名のタイムスタンプまたはファイルサイズが以前のリモート名と異なる場合、あるいは新しいサーバーがチェックポイント再開をサポートしていない場合 (HTTP のリモート名の場合)、BITS はダウンロードを最初からやり直します。それ以外の場合、転送は新しいサーバー上の同じ位置から再開されます。BITS は、転送済みのファイルを再転送することはありません。
リモート名がサーバーメッセージブロック (SMB) パスを示している場合、ジョブを再開した後に発生する可能性のあるエラーコードを次の表に示します。これらのエラーが発生すると、ジョブは BG_JOB_STATE_ERROR 状態になります。
| エラーコード | 説明 |
|---|---|
HRESULT_FROM_WIN32(ERROR_PATH_NOT_FOUND) |
ディレクトリが見つかりませんでした。 |
HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND) |
ファイルが見つかりませんでした。 |
HRESULT_FROM_WIN32(ERROR_ACCESS_DENIED) |
ユーザーは Val で指定されたファイルへのアクセス権を持っていません。 |
例
次の例は、SetRemoteName メソッドを呼び出してファイルのリモート名を変更する方法を示しています。この例では、IBackgroundCopyJob 変数 pJob が有効であり、ジョブに 1 つ以上のファイルが含まれていることを前提としています。
IBackgroundCopyJob *pJob;
IEnumBackgroundCopyFiles* pFiles = NULL;
IBackgroundCopyFile* pFile = NULL;
IBackgroundCopyFile2* pFile2 = NULL;
WCHAR* pRemoteFileName = NULL;
ULONG cFileCount = 0;
hr = pJob->Suspend();
hr = pJob->EnumFiles(&pFiles);
if (SUCCEEDED(hr))
{
//ジョブ内のファイル数を取得します。
hr = pFiles->GetCount(&cFileCount);
//ジョブ内のファイルを列挙します。
for (ULONG idx=0; idx<cFileCount; idx++)
{
hr = pFiles->Next(1, &pFile, NULL);
if (S_OK == hr)
{
//ファイルのローカル名を取得します。
hr = pFile->GetRemoteName(&pRemoteFileName);
if (SUCCEEDED(hr))
{
//このファイルのリモート名を置き換えるかどうかを判断します。
if (<CONDITIONGOESHERE>)
{
//IBackgroundCopyFile インターフェイスに対して QueryInterface を行い、IBackgroundCopyFile2
//インターフェイスポインターを取得する必要があります。SetRemoteName メソッドは IBackgroundCopyFile2 インターフェイスに含まれています。
hr = pFile->QueryInterface(__uuidof(IBackgroundCopyFile2), (void**)&pFile2);
if (S_OK == hr)
{
hr = pFile2->SetRemoteName(L"<NEWURLGOESHERE>");
if (FAILED(hr))
{
//エラー処理。
//ダウンロードジョブでない場合は E_NOTIMPL を返します。
//URL が無効な場合は E_INVALIDARG を返します。
}
}
else
{
//エラー処理。コンピューター上で動作している BITS のバージョンが BITS 2.0 未満の場合、
//QueryInterface は E_NOINTERFACE を返します。
}
}
CoTaskMemFree(pRemoteFileName);
}
pFile->Release();
pFile = NULL;
}
else
{
//エラー処理
break;
}
}
pFiles->Release();
pFiles = NULL;
}
hr = pJob->Resume(); //ジョブに強制的にシリアル化させます。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IBackgroundCopyFile2 "{83E81B93-0873-474D-8A8C-F2018B1A939C}" #usecom global IBackgroundCopyFile2 IID_IBackgroundCopyFile2 "{}" #comfunc global IBackgroundCopyFile2_GetFileRanges 6 var,var #comfunc global IBackgroundCopyFile2_SetRemoteName 7 wstr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。#define global IID_IBackgroundCopyFile2 "{83E81B93-0873-474D-8A8C-F2018B1A939C}" #usecom global IBackgroundCopyFile2 IID_IBackgroundCopyFile2 "{}" #comfunc global IBackgroundCopyFile2_GetFileRanges 6 sptr,sptr #comfunc global IBackgroundCopyFile2_SetRemoteName 7 wstr ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。