Forum Discussion
How to use AddOptionalPackageAsync?
I'm trying to build a MSIX solution for the [Julia](https://julialang.org/) language, but I'm stuck in that I can't get AddOptionalPackageAsync to work. In general, I'm using a PackagingLayout.xml that creates a bunch of packages and upload them all to a S3 bucket. I then also upload an appinstaller file.
Here is what works: I can install the main app from the appinstaller file, and it also successfully installs the optional packages that I specify as optional in the appinstaller file. What doesn't work is my attempt to install additional optional packages from code with a call to AddOptionalPackageAsync.
The code that I'm using to call AddOptionalPackageAsync looks like this:
auto packageToInstall = L"Julia-1.4.2";
auto res = catalog.AddOptionalPackageAsync(packageToInstall).get();
auto err = hresult_error(res.ExtendedError());
std::wcout << err.message().c_str() << std::endl;
This produces an output of "Access is denied.".
The content of the Julia.appinstaller is
<?xml version="1.0" encoding="utf-8"?>
<AppInstaller
xmlns="http://schemas.microsoft.com/appx/appinstaller/2017/2"
Version="1.0.0.0"
Uri="https://winjulia.s3-us-west-1.amazonaws.com/Julia.appinstaller" >
<MainBundle
Name="Julia"
Publisher="CN=Julialang"
Version="1.0.0.0"
Uri="https://winjulia.s3-us-west-1.amazonaws.com/Julia.appxbundle" />
<OptionalPackages>
<Bundle
Name="Julia-1.4.1"
Publisher="CN=Julialang"
Version="1.0.0.0"
Uri="https://winjulia.s3-us-west-1.amazonaws.com/Julia-1.4.1.appxbundle" />
</OptionalPackages>
<RelatedPackages>
<Bundle
Name="Julia-1.4.2"
Publisher="CN=Julialang"
Version="1.0.0.0"
Uri="https://winjulia.s3-us-west-1.amazonaws.com/Julia-1.4.2.appxbundle" />
</RelatedPackages>
<UpdateSettings>
<OnLaunch HoursBetweenUpdateChecks="0"/>
</UpdateSettings>
</AppInstaller>
The package `Julia-1.4.1` (which specified as an <OptionalPackages> child) gets successfully installed with the main app, and if I swap things and put `Julia-1.4.2` into the <OptionalPackages> parent and `Julia-1.4.1` into the <RelatedPackages> element, then `Julia-1.4.2` gets installed correctly (but then I can't get AddOptionalPackageAsync to install Julia-1.4.1.
I guess I'm passing the wrong string to AddOptionalPackageAsync, maybe?
Also, is there an API that I can call from within my main package that would essentially give me the family package ID of all the packages that I have listed in the appinstaller either in the <OptionalPackages> or in the <RelatedPackages> element?
Oh, and actually, I'm not even sure that putting things into the <RelatedPackages> parent is the correct move 🙂
Any help is much appreciated!
9 Replies
- Tanaka_JimhaFormer Employee
Hi davidanthoff,
Can you try add the second package under optional packages as well in your AppInstaller file something like this:
<OptionalPackages> <Bundle Name="Julia-1.4.1" Publisher="CN=Julialang" Version="1.0.0.0" Uri="https://winjulia.s3-us-west-1.amazonaws.com/Julia-1.4.1.appxbundle" /> <Bundle Name="Julia-1.4.2" Publisher="CN=Julialang" Version="1.0.0.0" Uri="https://winjulia.s3-us-west-1.amazonaws.com/Julia-1.4.2.appxbundle" /> </OptionalPackages>That should install both packages, or is that not your desired workflow?
As another install option from your code, consider using AddPackageByAppInstallerFileAsync to install packages defined in your AppInstaller file. You can find other AppInstaller file APIs here.
About using AddOptionalPackageAsync from code, can you try a few things:
- Add the packagemanagement capability to your app doing performing the install.
<Package> ... <Capabilities> <rescap:Capability Name="packageManagement" /> </Capabilities> ... </Package>​ - Use the packagefamilyname when calling AddOptionalPackageAsync - you can get the specific package's packagefamilyname by running Get-AppxPackage when it's installed on a machine. So you'd have to install it and run the command to get the correct value for future use. There's an explanation here
- Make sure your packages are part of a related set.
Cheers,
Tanaka
- davidanthoffBrass Contributor
Tanaka_Jimha Thanks! I tried all your suggestions, but no luck so far. Here are some more details:
I don't want to install all the optional dependencies at the same time when the main app is installed, so I don't think I should add all of them to the <OptionalPackages> element in the appinstaller file, right? I only want one of them installed with the main app, so I add that optional package to the <OptionalPackages> element, and then all the other optional packages I want to be able to install via an in-app option, so I add all of those packages to the <RelatedPackages> element in the appinstaller file. You can see the details of how I do this in the code that I posted with the original message.
I think https://docs.microsoft.com/en-us/uwp/api/windows.management.deployment.packagemanager.addpackagebyappinstallerfileasync?view=winrt-19041 for the same reason is also not the right tool to implement my in-app feature add thing, right? As far as I can tell, it doesn't provide an option to install a specific optional package of the app, right? Or did I miss an option there somewhere?
I did add <rescap:Capability Name="packageManagement" /> to my main app now, and it shows up in the UI when I install that, but it doesn't change the error message I get.
When I install all the optional packages on my system, and then run the following ps code:
> $x = Get-AppxPackage Julia* > $x.DependenciesI get this output:
Name : Julia-1.4.1 Publisher : CN=Julialang Architecture : X64 ResourceId : Version : 1.0.0.0 PackageFullName : Julia-1.4.1_1.0.0.0_x64__87dh6scs60qg2 InstallLocation : C:\Program Files\WindowsApps\Julia-1.4.1_1.0.0.0_x64__87dh6scs60qg2 IsFramework : False PackageFamilyName : Julia-1.4.1_87dh6scs60qg2 PublisherId : 87dh6scs60qg2 IsResourcePackage : False IsBundle : False IsDevelopmentMode : False NonRemovable : False IsPartiallyStaged : False SignatureKind : Developer Status : Ok Name : Julia-1.4.2 Publisher : CN=Julialang Architecture : X64 ResourceId : Version : 1.0.0.0 PackageFullName : Julia-1.4.2_1.0.0.0_x64__87dh6scs60qg2 InstallLocation : C:\Program Files\WindowsApps\Julia-1.4.2_1.0.0.0_x64__87dh6scs60qg2 IsFramework : False PackageFamilyName : Julia-1.4.2_87dh6scs60qg2 PublisherId : 87dh6scs60qg2 IsResourcePackage : False IsBundle : False IsDevelopmentMode : False NonRemovable : False IsPartiallyStaged : False SignatureKind : Developer Status : OkSo from this I take it that I should use "Julia-1.4.2_87dh6scs60qg2" as the string that I pass to AddOptionalPackageAsync? I'm doing that now, but I still get the same error message "Access is denied".
I do think everything is in one related set, I'm creating all the packages with a PackagingLayout.xml file that looks like this:
<PackagingLayout xmlns="http://schemas.microsoft.com/appx/makeappx/2017"> <!-- Main game --> <PackageFamily ID="Julia" FlatBundle="true" ManifestPath="appxmanifest.xml" ResourceManager="false"> <!-- x64 code package--> <Package ID="Julia-x64" ProcessorArchitecture="x64"> <Files> <File DestinationPath="Julia\Julia.exe" SourcePath="C:\Users\david\source\repos\WinJulia\Release\Julia.exe"/> <File DestinationPath="Images\*.png" SourcePath="Images\*.png"/> </Files> </Package> </PackageFamily> <PackageFamily ID="Julia-1.4.2" Optional="true" ManifestPath="juliaversions\julia-1.4.2-appxmanifest.xml" ResourceManager="false"> <Package ID="Julia-1.4.2.x64" ProcessorArchitecture="x64"> <Files> <File DestinationPath="Julia\**" SourcePath="C:\Users\david\source\repos\WinJulia\optionalpackages\julia-1.4.2\Julia\**"/> <File DestinationPath="Images\*.png" SourcePath="Images\*.png"/> </Files> </Package> </PackageFamily> <PackageFamily ID="Julia-1.4.1" Optional="true" ManifestPath="juliaversions\julia-1.4.1-appxmanifest.xml" ResourceManager="false"> <Package ID="Julia-1.4.1.x64" ProcessorArchitecture="x64"> <Files> <File DestinationPath="Julia\**" SourcePath="C:\Users\david\source\repos\WinJulia\optionalpackages\julia-1.4.1\Julia\**"/> <File DestinationPath="Images\*.png" SourcePath="Images\*.png"/> </Files> </Package> </PackageFamily> <PackageFamily ID="Julia-1.4.0" Optional="true" ManifestPath="juliaversions\julia-1.4.0-appxmanifest.xml" ResourceManager="false"> <Package ID="Julia-1.4.0.x64" ProcessorArchitecture="x64"> <Files> <File DestinationPath="Julia\**" SourcePath="C:\Users\david\source\repos\WinJulia\optionalpackages\julia-1.4.0\Julia\**"/> <File DestinationPath="Images\*.png" SourcePath="Images\*.png"/> </Files> </Package> </PackageFamily> </PackagingLayout>And I believe that should create all packages as being in one related set, right?
- Tanaka_JimhaFormer Employee
Hi davidanthoff
Access Denied means you're having permission issues calling the API. Our devs said the fastest way to root cause will be to get logs. Can you please make a Feedback Hub submission capturing the error in the Developer Platform > App Deployment category:
After capturing the issue, can you also attach the appxmanifest.xml files of your main app and optional packages with the submission. Please send me a link to the issue once you're done.
Thanks,
Tanaka
- Add the packagemanagement capability to your app doing performing the install.