microsoft / WindowsAppSDK

The Windows App SDK empowers all Windows desktop apps with modern Windows UI, APIs, and platform features, including back-compat support, shipped via NuGet.
https://docs.microsoft.com/windows/apps/windows-app-sdk/
MIT License
3.86k stars 328 forks source link

Web App auto-update via MSIX package doesn't support other AppInstaller options like Showing A User Prompt to Upgrade #1067

Closed ivberg closed 2 weeks ago

ivberg commented 3 years ago

Describe the bug Web App auto-update via MSIX package doesn't seem to work. I publish .msix / .appinstaller to a website and when I start the app it doesn't seem to check/update. I have to manually go to the website to force an update despite the VS UI settings making it appear it should.

This might be a MSIX bug (see details below) or even VS bug since it generates the settings (although not as likely).

Steps to reproduce the bug

Steps to reproduce the behavior:

  1. Create a basic WinAppSDK 0.8 app - https://docs.microsoft.com/en-us/windows/apps/windows-app-sdk/
  2. In latest VS 16.10.3, right click package project - E.g MyApp (Package) and choose Publish -> Create App Packages
  3. Go through the wizard and choose a. Sideloading - Enable automatic updates b. Sign package however you need to - e.g with dev cert c. Configure packages however u want - E.g Version 0.1 (the first version) d. Update settings - Installer Location (some website). e.g https://myapp.azurewebsites.net/ e. How often should this application check for updates? Choose - "Every time the application runs"
  4. Click create and zip / copy to your website - e.g. https://myapp.azurewebsites.net/
  5. Look in the .wapproj and see the settings - MyApp (Package)\MyAppUI (Package).wapproj a. <GenerateAppInstallerFile>True</GenerateAppInstallerFile> b. <HoursBetweenUpdateChecks>0</HoursBetweenUpdateChecks>
  6. Verify on MSDN HoursBetweenUpdateChecks behavior that the UI implies https://docs.microsoft.com/en-us/windows/msix/app-installer/update-settings a. HoursBetweenUpdateChecks: An integer that indicates how often (in how many hours) the system will check for updates to the app. “0” to “255” inclusive. The default value is 24 (if this value is not specified). For example if HoursBetweenUpdateChecks = 3 then when the user launches the app, if the system has not checked for updates within the past 3 hours, it will check for updates now. b. Reading MSDN it seems ShowPrompt=false but the update should happen in the background before activation
  7. appinstaller file will have content like this b. <UpdateSettings> <OnLaunch HoursBetweenUpdateChecks="0" /> </UpdateSettings>
  8. Install 0.1 of app on a box from https://myapp.azurewebsites.net/
  9. Make a cosmetic change to the app you can visually see. Go through steps 2-5 but rev the version to say 0.2
  10. Zip deploy the app again
  11. Close & Launch the app again but notice it doesn't seem to auto-update to 0.2 or your new UI

Note: MSIX is supposed to have ClickOnce like behavior but ClickOnce always updates properly for this scenario. It seems the default settings and behavior don't for WinAppSDK apps / MSIX despite the VS UI and settings implying that it should

Expected behavior App auto updates on launch as implied by VS Wizard UI and MSDN docs

Screenshots

Version Info NuGet package version: WinAppSDK / ReUnion 0.8.1

Windows 10 version Saw the problem?
Win11 Insider Build (22142) Yes

Additional context Will attempt to play/generate other settings like ShowPrompt=true and AutomaticBackgroundTask=true https://docs.microsoft.com/en-us/windows/msix/app-installer/update-settings

ivberg commented 3 years ago

Interestingly enough here is another page that talks about this - I don't know if it's out of date or not vs the other MSDN page. All this implies (to me) that updates will be done on launch (even if they don't force the user to do so - but I am not sure how that's going to happen without a UI)

https://docs.microsoft.com/en-us/uwp/schemas/appinstallerschema/element-onlaunch

Setting the ShowPrompt="true" attribute currently shows a prompt for UWP applications but not for desktop applications that have been packaged in a Windows app package (that is, desktop applications that use the Desktop Bridge). For desktop applications, this functionality provides a silent update; the same default functionality provided by the OnLaunch element.

joshusto commented 3 years ago

Hi ivberg,

For "8. Install 0.1 of app on a box", how are you installing the app? If it's by clicking on the Msix or MsixBundle, then that won't link the app to its auto update settings. Do auto updates work if you perform the initial install through the appinstaller file link? Example: www.contoso.com/sampleapp.appinstaller

You can also try installing through PowerShell with "Add-AppxPackage -AppInstallerFile <your .appinstaller file uri>"

Thanks, Jonathan

ivberg commented 3 years ago

I edited step 9 to be more clear - 9. Install 0.1 of app on a box from https://myapp.azurewebsites.net/

ivberg commented 3 years ago

Also, putting this in the MyApp (Package)\MyAppUI (Package).wapproj <ShowPrompt>True

Does NOT seem to generate the equivalent in .appinstaller file <UpdateSettings node

ivberg commented 3 years ago

Also @joshusto please inform what client side MSIX logs you guys recommend to gather to prove or disprove the apparent behavior. I could have been mistaken sometimes if the app silently updated, but the lack of ShowPrompt=True makes this harder to visibly confirm vs say ClickOnce defaults which always show a dialogue upon update available. Per above, what VS .wapproj settings is needed to make ShowPrompt=True generated?

joshusto commented 3 years ago

Also @joshusto please inform what client side MSIX logs you guys recommend to gather to prove or disprove the apparent behavior. I could have been mistaken sometimes if the app silently updated, but the lack of ShowPrompt=True makes this harder to visibly confirm vs say ClickOnce defaults which always show a dialogue upon update available. Per above, what VS .wapproj settings is needed to make ShowPrompt=True generated?

I don't believe that the wapproj settings have a mapping for each AppInstaller file setting. To edit these, you'd need to change the generated appinstaller file that gets placed on your https://myapp.azurewebsites.net/ page. For example, you can change UpdateSettings in the generated appinstaller file to the following:

<UpdateSettings> 
    <OnLaunch HoursBetweenUpdateChecks="0" ShowPrompt="true" UpdateBlocksActivation="true"/>
</UpdateSettings>

On the impacted build, try running the following in an elevated PowerShell:

1) Get-AppxPackage *<your package name or a substring from the name>*
2) $pm = new-object windows.management.deployment.packagemanager
3) $package = $pm.FindPackage("<PackageFullName from step 1>")
4) $package.GetAppInstallerInfo().Uri

In step 4, does $package.GetAppInstallerInfo().Uri return a non-null value that shows your appinstaller file? If not, then the app didn't link to its auto-update settings when it got installed. If the value was null, go to the AppInstaller file that VS generated then copy the following URI section:

<?xml version="1.0" encoding="utf-8"?>
<AppInstaller
    Uri="https://example.contoso.com/SampleApp_x86.appinstaller"
    Version="1.0.0.0" xmlns="http://schemas.microsoft.com/appx/appinstaller/2017/2"> 

With the copied section, try running the below command in PowerShell:

Add-AppxPackage -AppInstallerFile <uri copied from "Uri" value above>

When you repeat steps 3 and 4, you should now see a value from $package.GetAppInstallerInfo().Uri and the app should update in the background when you publish a change. Note: It's necessary to update the AppInstaller file's MainPackage/MainBundle element with the new version of the package. For example, if the AppInstaller file previously had

<MainPackage
    Name="69f67761-c87e-4d21-ad49-400f427947ac"
    Version="1.0.0.0"
    Publisher="CN=joshusto"
    Uri="https://example.contoso.com/SampleAppV1.msix"
    ProcessorArchitecture="x86" />

you'd need to change it to

<MainPackage
    Name="69f67761-c87e-4d21-ad49-400f427947ac"
    Version="2.0.0.0"
    Publisher="CN=joshusto"
    Uri="https://example.contoso.com/SampleAppV2.msix"
    ProcessorArchitecture="x86" />

before the update can take place. Assuming you're using the default VS settings, the update occurs in the background on launch and it won't be applied until the next time the app opens. You can confirm that the update is getting staged by running the following in an elevated PowerShell:

Get-AppxPackage -AllUsers *<substring with your package name>*

If auto updates are working correctly, you should see v2 of your package with a "Staged" status shortly after launching your application. The update will be applied the next time the application starts.

ivberg commented 3 years ago

I am still trying to determine if the auto-updating silent behavior in the background works (at all). I personally haven't seen it work successfully yet.

I did find out where some logs might be - https://docs.microsoft.com/en-us/windows/msix/app-installer/troubleshoot-appinstaller-issues

App Installer event logs The app deployment infrastructure emits logs that are often useful for debugging installation issues via the Windows Event Viewer: Application and Services Logs -> Microsoft -> Windows -> AppxDeployment-Server

ivberg commented 3 years ago

Ok - I did see a silent auto-update appear to work today! Please leave this issue open though so that WinAppSDK / wapproj and VS support the other appinstaller settings like ShowPrompt. Otherwise, we have to write a workaround to re-write the .appinstaller after build. The event log showing the update in Microsoft-Windows-AppXDeploymentServer/Operational was:

Started deployment UpdateUsingAppInstallerOperation operation on a package with main parameter MyApp_1.0.0.0_x64__8wekyb3d8bbwe and Options 0 and 0. See http://go.microsoft.com/fwlink/?LinkId=235160 for help diagnosing app deployment issues.

conorlawton commented 1 year ago

This issue persists. Details ommitted but I can assure you that the endpoints and certificate are correct.

<?xml version="1.0" encoding="utf-8"?>
<AppInstaller
    Uri="http://domain/myapp.appinstaller"
    Version="0.1.1.0" xmlns="http://schemas.microsoft.com/appx/appinstaller/2017/2">
    <MainPackage
        Name="49d89e30-8b49-4435-844d-14ed2c10de79"
        Version="0.1.1.0"
        Publisher=""
        Uri="http://domain/apps/app.msix"
        ProcessorArchitecture="x86" />
    <UpdateSettings>
        <OnLaunch
            HoursBetweenUpdateChecks="1" />
    </UpdateSettings>
</AppInstaller>

The following data is logged in the Event Viewer: Started deployment UpdateUsingAppInstallerOperation operation on a package with main parameter 49d89e30-8b49-4435-844d-14ed2c10de79_0.1.2.0_x86_stehcx39bde72 and Options 0 and 0. See http://go.microsoft.com/fwlink/?LinkId=235160 for help diagnosing app deployment issues.

The installed package name matches that of the one in the above log entry. The appinstaller file at the endpoint points to the next update (0.1.2.0). The automatic update appears to start but the actual update does not happen. I will open a new issue if required.

LegendaryBlair commented 2 weeks ago

@conorlawton you will need to change your appinstaller scheme to http://schemas.microsoft.com/appx/appinstaller/2021, which supports new ShowPrompt or UpdateBlocksActivationattribute, then update the OnLaunch section like the following. <OnLaunch HoursBetweenUpdateChecks="0" ShowPrompt="true" UpdateBlocksActivation="true"/> See app installer file versioning

LegendaryBlair commented 2 weeks ago

Here's the summary of the solution:

  1. Add property <GenerateAppInstallerFile>True</GenerateAppInstallerFile> to the WapProj so that VS can generate the .appInstaller file.
  2. If you want to use the auto-update feature, you will need to change the .appinstaller file manually. a. change appInstaller scheme to http://schemas.microsoft.com/appx/appinstaller/2021, the default schema http://schemas.microsoft.com/appx/appinstaller/2017/2 generated by visual studio does not support ShowPrompt attribute b. Set ShowPrompt to true in OnLaunch element, it may look like <OnLaunch HoursBetweenUpdateChecks="0" ShowPrompt="true" UpdateBlocksActivation="true"/> c. Set UpdateBlocksActivation to true if you want to force user to update the app before use.
  3. Upload the updated appinstaller file and corresponding package to the hosting website.

References: app installer file versioning

LegendaryBlair commented 2 weeks ago

This issue is not related to WinAppSDK in particular, and it's related to appInstaller versioning. Given solution is provided, hence closing the issue.