Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Downloading files using BITS gives Transient Error

1,319 views
Skip to first unread message

Nishant

unread,
Nov 6, 2008, 1:17:53 PM11/6/08
to
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;
}

frank cao [msft]

unread,
Dec 11, 2008, 1:55:03 PM12/11/08
to
Please use the following command to list BITS job properties and compare the
properties between the jobs created by bitsadmin and jobs created by your
app:

bitsadmin /list /all /users /verbose


"Nishant" wrote:

> 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)
> {
> .....

> .....

0 new messages