Downloading files using BITS gives Transient Error
Hi,
I have created an application that tries to get a set of files using
BITS from a remote machine..The only response I'm getting is Transient
Error when queried for Job State..The function is as given below..I
have tried MSDN but could not clearly understand the issues with that.
I tried testing the URL created with bitsadmin.exe and it works.
The application is deployed as Windows Service with LocalSystemAccount
logon. Operating systems involved are WinXPSP2/SP3, Win2K SP4. Please
help to know what i'm doing wrong here..
Thanks,
NKH
int BITSGet(WCHAR *filelist, WCHAR* src, WCHAR* destination, long
WebPort)
{
.....
.....
BG_FILE_INFO fileInfo[MAX_FILES] = { 0 };
for(int i = 0; i < fileCount; ++i)
{
fileInfo[i].RemoteName = source[i];
fileInfo[i].LocalName = dest[i];
}
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
if (SUCCEEDED(hr))
{
hr = CoCreateInstance(__uuidof(BackgroundCopyManager),NULL,
CLSCTX_LOCAL_SERVER,
__uuidof(IBackgroundCopyManager),
(void**) &g_pbcm);
if (SUCCEEDED(hr))
{
cout<<"Created instance of BackgroundCopyManager"<<endl;
hr = g_pbcm->CreateJob(L"DownloadClientFiles",
BG_JOB_TYPE_DOWNLOAD, &JobId, &pJob);
if (SUCCEEDED(hr))
{
cout<<"Created job instance"<<endl;
hr = pJob->AddFileSet(fileCount, fileInfo);
if (FAILED(hr))
{
if(hr == E_ACCESSDENIED)
{
cout<<"Access denied"<<endl;
}
else if(hr == E_INVALIDARG)
{
cout<<"Invalid Arguments for BITS"<<endl;
}
else if(hr == BG_E_TOO_MANY_FILES)
{
cout<<"Too many files in the BITS download
queue"<<endl;
}
else
{
cout<<"Error while adding file set to the
job"<<endl;
}
return 2;
}
else if(hr == S_OK)
{
cout<<"Added file to the job"<<endl;
}
//The default priority level for a job is
BG_JOB_PRIORITY_NORMAL.
hr = pJob->SetPriority(BG_JOB_PRIORITY_FOREGROUND);
if (FAILED(hr))
{
cout<<"priority failed"<<endl;
}
hr = pJob->Resume();
if(FAILED(hr))
{
if(hr == BG_E_EMPTY)
{
cout<<"No files to transfer for job..Problem
with BITS URL"<<endl;
}
else if(hr == BG_E_INVALID_STATE)
{
cout<<"Invalid job state for job"<<endl;
}
}
else if(SUCCEEDED(hr))
{
cout<<"Job resumed"<<endl;
}
do
{
WaitForSingleObject(hTimer, INFINITE);
//Use JobStates[State] to set the window text in a
user interface.
hr = pJob->GetState(&JobState);
if (FAILED(hr))
{
//Handle error
cout<<"Failed to get job state for
job"<<endl;
}
errReturn(JobState);
if (BG_JOB_STATE_TRANSFERRED == JobState)
{
cout<<"Job completed"<<endl;
hr = pJob->Complete();
//cancel the timer and close it before
exiting
CancelWaitableTimer(hTimer);
CloseHandle(hTimer);
return 0;
}
if (BG_JOB_STATE_CONNECTING == JobState)
{
cout<<"Connecting"<<endl;
}
if (BG_JOB_STATE_SUSPENDED == JobState)
{
cout<<"Suspended"<<endl;
}
if (BG_JOB_STATE_ERROR == JobState)
{
cout<<"job state returned error"<<endl;
errReturn(JobState);
hr = pJob->GetError(&pError);
if (SUCCEEDED(hr))
{
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)
{
cout<<"Could not access the
specified URL"<<endl;
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();
}
errReturn(JobState);
pJob->Cancel();
//cancel the timer and close it before
exiting
CancelWaitableTimer(hTimer);
CloseHandle(hTimer);
return 1;
}
else if(BG_JOB_STATE_TRANSIENT_ERROR == JobState)
{
cout<<"Transient Error for job"<<endl;
errReturn(JobState);
hr = pJob->SetMinimumRetryDelay(60);
if(FAILED(hr))
cout<<"failed delay"<<endl;
else
pJob->Resume();
}
//Call pJob->GetError(&pError); to retrieve an
IBackgroundCopyError interface
//pointer which you use to determine the cause of
the error.
else if (BG_JOB_STATE_TRANSFERRING == JobState)
{
cout<<"Transferring"<<endl;
}
//Call pJob->GetProgress(&Progress); to determine
the number of bytes
//and files transferred.
} while (BG_JOB_STATE_TRANSFERRED != JobState &&
BG_JOB_STATE_ERROR != JobState);
CancelWaitableTimer(hTimer);
CloseHandle(hTimer);
}
else
{
cout<<"job creation failed"<<endl;
}
}
else
{
cout<<"Failed initialisation of BackgroundCopyManager COM
Interface"<<endl;
}
}
else
{
cout<<"Error while initialising COM Instance for BITS"<<endl;
}
::CoUninitialize();
return 3;
}