I have an app using BITS to download files. When I packaged my app with MSIX, it started behaving strangely. Every background copy job started from the packaged app transitions into the BG_JOB_STATE_TRANSIENT_ERROR state immediately and stays that way until the app is closed or becomes inactive/minimized. This behavior is still unclear.
Using bitsadmin /list /allusers /verbose, I got this:
GUID: {A8C6001C-182D-424B-86DC-6C8E131E185B} DISPLAY: 'Download an update'
TYPE: DOWNLOAD STATE: TRANSIENT_ERROR OWNER: ....
PRIORITY: NORMAL FILES: 0 / 1 BYTES: 0 / UNKNOWN
CREATION TIME: 9/2/2022 11:33:08 AM MODIFICATION TIME: 9/2/2022 11:33:58 AM
COMPLETION TIME: UNKNOWN ACL FLAGS:
NOTIFY INTERFACE: UNREGISTERED NOTIFICATION FLAGS: 3
RETRY DELAY: 600 NO PROGRESS TIMEOUT: 1209600 ERROR COUNT: 0
PROXY USAGE: PRECONFIG PROXY LIST: NULL PROXY BYPASS LIST: NULL
ERROR FILE: ...
ERROR CODE: 0x8020006e - The background access settings of the job's owner app prevent the job from transferring at this time.
ERROR CONTEXT: 0x00000002 - The error occurred in the Background Intelligent Transfer Service (BITS) queue manager.
DESCRIPTION:
JOB FILES:
0 / UNKNOWN WORKING ...
NOTIFICATION COMMAND LINE: none
owner MIC integrity level: MEDIUM
owner elevated ? false
Peercaching flags
Enable download from peers :false
Enable serving to peers :false
CUSTOM HEADERS: NULL
I tried to set the job's priority, but it didn't help. I also had a hunch that I might need to enable some capability in the MSIX manifest, but I haven't found anything. I also tried to use the BackgroundDownloader from my WPF app, but it looks like UWP only.
Is it a known behavior? Anything I can do to make it transfer bites while the packaged app is running?
My code:
- it's based on BITS-Manager
- it works great if the app is not pacakged
- I was able to reproduce the same behavior with BITS-Manager as well
internal class DownloadJob : BITS.IBackgroundCopyCallback
{
private readonly TaskCompletionSource taskCompletionSource;
private BITS.IBackgroundCopyJob job;
public DownloadJob()
{
this.taskCompletionSource = new TaskCompletionSource();
this.job = null;
}
public Task Start(string name, string url, string path, Action<byte[]> onJobIdCreated)
{
try
{
var manager = new BITS.BackgroundCopyManager1_5();
GUID jobGuid;
manager.CreateJob(
name,
BITS.BG_JOB_TYPE.BG_JOB_TYPE_DOWNLOAD,
out jobGuid,
out job);
onJobIdCreated(jobGuid.GetBytes());
job.AddFile(url, path);
job.SetDownloadCost(Costs.TRANSFER_STANDARD);
job.DisablePeerCaching();
this.RegisterListenerFor(job);
job.Resume();
}
catch
{
job?.Cancel();
taskCompletionSource.TrySetException(new DownloadFailedException());
}
return taskCompletionSource.Task;
}
public void JobTransferred(BITS.IBackgroundCopyJob job)
{
job?.Complete();
taskCompletionSource.TrySetResult();
}
public void JobError(BITS.IBackgroundCopyJob job, BITS.IBackgroundCopyError error)
{
job?.Cancel();
taskCompletionSource.TrySetException(new DownloadFailedException());
}
public void JobModification(BITS.IBackgroundCopyJob pJob, uint dwReserved)
{
}
}
The packaging manifest:
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap rescap">
<Identity
Name="..."
Publisher="..."
Version="1.0.0.0" />
<Properties>
<DisplayName>BITSManagerPackaged</DisplayName>
<PublisherDisplayName>...</PublisherDisplayName>
<Logo>Images\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
<TargetDeviceFamily Name="Windows.Desktop" MinVersion="10.0.14393.0" MaxVersionTested="10.0.14393.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="$targetentrypoint$">
<uap:VisualElements
DisplayName="BITSManagerPackaged"
Description="BITSManagerPackaged"
BackgroundColor="transparent"
Square150x150Logo="Images\Square150x150Logo.png"
Square44x44Logo="Images\Square44x44Logo.png">
<uap:DefaultTile Wide310x150Logo="Images\Wide310x150Logo.png" />
<uap:SplashScreen Image="Images\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
</Capabilities>
</Package>