Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: Easily enable building any Windows app from a single project template #491

Closed
stevenbrix opened this issue Feb 26, 2021 · 17 comments
Assignees
Labels
area-DeveloperTools Issues related to authoring (source and IDL), debugging, HotReload, LiveVisualTree, VS integration feature proposal
Milestone

Comments

@stevenbrix
Copy link

stevenbrix commented Feb 26, 2021

Proposal: Easily enable building any Windows app from a single project template

Summary

Today, there are many different "types" of Windows apps:

  1. Unpackaged
  2. Packaged Desktop
  3. Sparse Packages
  4. UWP

The development workflow for all of these different app types is vastly different, and in the case of Sparse Packages, there is no tooling support whatsoever. This proposal is to unify all of these paradigms into a single template, and allow developers to choose which app type they are building by setting a single MSBuild property in their project file:

Unpackaged app

<PropertyGroup>
  <WindowsPackageType>None</WindowsPackageType>
</PropertyGroup>

Sparse packaged app

<PropertyGroup>
  <WindowsPackageType>Sparse</WindowsPackageType>
</PropertyGroup>

Packaged desktop app

<PropertyGroup>
  <WindowsPackageType>Desktop</WindowsPackageType>
</PropertyGroup>

UWP app

<PropertyGroup>
  <WindowsPackageType>Universal</WindowsPackageType>
</PropertyGroup>

Rationale

  • The Windows app ecosystem is greatly divided in terms of developer experience. Project Reunion is all about bringing them together.
  • It allows developers to be flexible in their app choices. They can start with a UWP, and easily change to Desktop with minimal changes.
  • The tooling for this will be decoupled from VS, allowing for greater flexibility and also allow tooling and runtime to ship together.

Scope

Capability Priority
Allow .NET developers to build UWP apps that use .NET6 Must
Allow developers to no longer require the Windows Application Packaging project for packaged Desktop Must
Allow developers to use the existing workflows for creating app packages and publishing to the store Must
No changes to package.appxmanifest in order to switch between Sparse Universal or Desktop app Must
Enable .NET developers to build unpackaged apps using .NET CLI Must
Integrate with .NET ClickOnce deployment publishing Must
Allow developers to change WindowsPackageType in VS UI Should
Enable .NET developers to build Packaged apps using .NET CLI Could

Important Notes

There should be some default behavior that users can expect. This will be defined as:

  1. If there is no Package.appxmanifest in the project, then WindowsPackageType defaults to None
  2. If there is a Package.appxmanifest in the project, then WindowsPackageType defaults to Desktop.

Open Questions

Is WindowsPackageType the right property name? Should the existence of the Package.appxmanifest default into a Sparse app, and then developers just choose their container/package? This would mean there are only two options: Desktop and Universal.

@riverar
Copy link
Contributor

riverar commented Feb 26, 2021

Some feedback/questions after reading the referenced specification.

[5.2.1.1 - Manifest Files] All new WinUI3 apps will have a package.appxmanifest file, but the SxS manifest should be removed.

What if a customer doesn't want to assert PerMonitorV2 support in their fusion manifest? Or add comctl? Or OS compat guids? Or long file path support? (Example from our app.)

[5.2.2 - WinUI3 Specific Tooling Requirements] Since WinUI has C++ customers, a special tool for generating the main method (i.e. Xaml compiler), which registers the Sparse Package and Dynamic Dependencies registration will be required.

Consider adding a switch around this behavior as some customers may want to handle registration themselves or not register in some scenarios.

[5.2.3 - Choosing your Windows APIs] The UWP target platform selector is problematic with Reunion. The Reunion APIs are designed to ship out of band with the OS, and with this, users are able to select Windows versions that are not compatible with their Reunion packages. This UI should just be disabled, since we hard code the TargetPlatformVersion (TPV) in the project file to match what reunion supports.

As a developer, I feel that dialog (and the subsequent property) are my only safeguards from accidentally bringing in code that does not support my app's target OS matrix. By disabling this dialog and fiddling with the property directly, I feel like I lose control over which OS versions I target. (Why does Reunion think it knows which TPV I want?)

[5.3.3 - Creating App Bundles and Publishing to the Microsoft Store]

msbuild WindowXamlAppCs.sln /m /p:Platform=x64 /p:UapAppxPackageBuildMode=StoreOnly /p:AppxBundle=Always /p:AppxBundlePlatforms="x64|arm64" /p:Configuration=Release

This invokes MSBuild in a recursive manner which rebuilds the project for multiple architectures. This behavior adds enormous complexity to the build and is difficult to maintain. Furthermore, a complex build is a slow build, and so this behavior will not be carried forward. Instead, we will only build individual .msix files per architecture, and we will enable developers to submit their apps to the store either by using the Windows Store Azure DevOps task, and the VS Publish->Create App Packages UI will be updated to handle individual .msix files.

The Windows Store Azure DevOps task is ... not good. Have you considered promoting StoreBroker use instead?

Would like to see more detail in this area. I don't see any consideration for p:AppxPackageSigningEnabled=false, p:GenerateAppInstallerFile, /p:UapAppxPackageBuildMode=CI, or other of those hidden nightmares.

[#491, WindowsPackageType enum examples]

<PropertyGroup>
 <WindowsPackageType>Sparse</WindowsPackageType>
</PropertyGroup>

Sounds okay on the surface. I wonder if adding a Desktop or DesktopMsix preface (or similar) would help with clarity here?

Example:

enum {
  None,
  DesktopMsix,
  DesktopMsixSparse,
  Universal
}

Or if you'd like to decouple the packaging technology from the enum:

enum {
  None,
  Desktop,
  DesktopSparse,
  Universal
}

[#491, Open Questions]
Is WindowsPackageType the right property name? Should the existence of the Package.appxmanifest default into a Sparse app, and then developers just choose their container/package? This would mean there are only two options: Desktop and Universal.

Property name sounds good. With regards to .appxmanifest sensing, I would prefer if no magic behavior occurs and if I chose the wrong WindowsPackageType, I'd fail. Defaulting to the most confusing / least used packaging format will also be super confusing. (Theoretical customer: Why is my MSIX empty?!)

@riverar
Copy link
Contributor

riverar commented Feb 27, 2021

Some other miscellanea before I forget:

  • Packaging toolset must support the packaging of "executable" projects and all dependencies. That is, it should support the ability to gather up the artifacts for both a hypothetical Exe.csproj and AddonDll.csproj, overlaying the outputs. The Windows Application Packaging project does not support this today and it's a pain point.
  • Didn't see any talk about Package.StoreAssociation.xml

@stevenbrix
Copy link
Author

Thank you @riverar for the feedback!

[5.2.1.1 - Manifest Files] All new WinUI3 apps will have a package.appxmanifest file, but the SxS manifest should be removed.

What if a customer doesn't want to assert PerMonitorV2 support in their fusion manifest? Or add comctl? Or OS compat guids? Or long file path support? (Example from our app.)

@riverar they can opt-out. This is only about the default for new projects, projects with a lot of existing legacy will just move their apps forward.

Consider adding a switch around this behavior as some customers may want to handle registration themselves or not register in some scenarios.

This switch already exists, you can disable the compiler generated main by adding this:

<DefineConstants>DISABLE_XAML_GENERATED_MAIN</DefineConstants>

As a developer, I feel that dialog (and the subsequent property) are my only safeguards from accidentally bringing in code that does not support my app's target OS matrix. By disabling this dialog and fiddling with the property directly, I feel like I lose control over which OS versions I target. (Why does Reunion think it knows which TPV I want?)

The problem with the current TPV selector is it creates discrepancies between what we support and what you can choose. Choosing your Reunion libraries in Nuget is essentially equivalent to selecting your TPV.

The Windows Store Azure DevOps task is ... not good. Have you considered promoting StoreBroker use instead?

This is great feedback, thank you! What do you like about StoreBroker over the dev ops task? I haven't found good documentation on this subject, so I'm eager to hear your thoughts.

Would like to see more detail in this area. I don't see any consideration for p:AppxPackageSigningEnabled=false, p:GenerateAppInstallerFile, /p:UapAppxPackageBuildMode=CI, or other of those hidden nightmares.

Also great feedback. What is your preference for AppxPackageSigningEnabled and GenerateAppInstallerFile? The UapAppxPackageBuildMode properties shouldn't do anything. We should use the SelfContained property to determine whether or not the MSIX will contain all of the .NET/Reunion assemblies in them or not.

Packaging toolset must support the packaging of "executable" projects and all dependencies. That is, it should support the ability to gather up the artifacts for both a hypothetical Exe.csproj and AddonDll.csproj, overlaying the outputs. The Windows Application Packaging project does not support this today and it's a pain point.

I'm a bit confused by this one, I'm fairly aware of how the packaging project works, and this is how I would describe it works. Do you have a repro project or issue to look at?

Didn't see any talk about Package.StoreAssociation.xml

I wasn't expecting any difference here, but perhaps it's worth calling that out? Is there something you'd like to see?

@stevenbrix
Copy link
Author

Property name sounds good. With regards to .appxmanifest sensing, I would prefer if no magic behavior occurs and if I chose the wrong WindowsPackageType, I'd fail. Defaulting to the most confusing / least used packaging format will also be super confusing. (Theoretical customer: Why is my MSIX empty?!)

This is good feedback. I proposed this because the majority of Windows developers aren't building packaged apps. What do you think is confusing about Sparse packages?

@andrewleader andrewleader added area-DeveloperTools Issues related to authoring (source and IDL), debugging, HotReload, LiveVisualTree, VS integration and removed needs-triage labels Mar 1, 2021
@nickrandolph
Copy link

I don't believe this proposal, nor the associated spec has been well thought out at all - sorry to be blunt but we only get one shot at this and the way things are being proposed is going to lead to more confusion. I've already commented on the spec, along with @DrusTheAxe, indicating that the choice of app model types are completely meaningless and in no way reflect what you're trying to achieve.

Reunion should be able developers enabling features, not contorting their app to fit into some set of pre-defined packaging models. For example:

  • As a developer if I want to be able to start with an unpackaged app that builds and runs without any need for packaging.
  • I might later decide that my application needs an Identity (so it can use notifications, appdata etc) - to enable this I should be able to go to the Identity tab of the Project Properties, check Identity box and then add any additional information required for Identity.
  • I might decide later that I want to take advantage of improved security model offered by the Windows App Container. Again, Project Properties, select Security tab and check the "Run in Windows App Container" box (there might be other properties on this tab relating to trust level etc).
  • To make my application awesome I also want to take advantage of the modern app lifecycle (i.e. the uwp app lifecycle). For this all I need to do is override the appropriate lifecycle methods/events. Whatever OS level registrations that need to happen should be automatically done for me.

I'm not clear on all the nuances that I've properly overlooked but I do see that the current proposal/spec in no way clears up the confusion that exists regarding desktop v uwp v packaging v sparse packaging etc

@andrewleader
Copy link
Contributor

Excellent feedback @nickrandolph. For some of these points, like deciding "my app needs Identity so I can use notifications", the whole purpose of the Project Reunion effort is to make it so that you do NOT need to be MSIX packaged.

So, if we do Project Reunion correctly, there should not be any API that you have to be deciding "Hmm, I need to have identity/MSIX". Unpackaged vs packaged apps will be on the same level playing field.

Thus, being packaged MSIX vs unpackaged is purely a distribution/security choice (if we as Reunion do our jobs right). Does that help clarify things some? I know we might have not made that story clear, we're working on making this story clearer (an updated README file coming out later this week should help a bit).

@nickrandolph
Copy link

@andrewleader in terms of Identity that's exactly how I see it - basically Identity is something a developer can opt in/out of via a checkbox in project properties (irrespective of how it's implemented). On an implementation level for Identity I was under the impression you'd still need to at least do a sparse package, even if this was opaque to the developer (i.e. the package is built and included as an asset alongside the application, or is dynamically generated at runtime so identity can be registered).

I also agree packaged v unpackaged is just a single checkbox. Again an opt in/out for developer to take advantage of the distribution/security model.

What I don't understand is the different "app model types" specified in this issue/spec. What do I get from switching between Desktop and Universal packaging? Is this supposed to reflect whether the app runs in the app container or not? If so, this should be a checkbox itself (i.e. first check box is to enable packaging, second checkbox (assuming first is selected) is for the app container).

My overall point is this is about enabling features based on what developers want to achieve.

@riverar
Copy link
Contributor

riverar commented Mar 4, 2021

The Windows Store Azure DevOps task is ... not good. Have you considered promoting StoreBroker use instead?

This is great feedback, thank you! What do you like about StoreBroker over the dev ops task? I haven't found good documentation on this subject, so I'm eager to hear your thoughts.

My experience: The Visual Studio Team Services extension for the Windows Store task breaks a lot, has poor support, and isn't used internally (e.g. Xbox). StoreBroker has great support, is stable, has excellent documentation, and is used internally. Just something to think about.

Would like to see more detail in this area. I don't see any consideration for p:AppxPackageSigningEnabled=false, p:GenerateAppInstallerFile, /p:UapAppxPackageBuildMode=CI, or other of those hidden nightmares.

Also great feedback. What is your preference for AppxPackageSigningEnabled and GenerateAppInstallerFile? The UapAppxPackageBuildMode properties shouldn't do anything. We should use the SelfContained property to determine whether or not the MSIX will contain all of the .NET/Reunion assemblies in them or not.

We hardcode AppxPackageSigningEnabled to false in our builds and separate build/signing tasks for various reasons. But I don't have a preference, just brought it up to ensure awareness. For example, there's hidden Packaging Project behavior where sideload packages are not generated in Debug configurations. "It's dangerous to go alone! Take this. 🗡"

Packaging toolset must support the packaging of "executable" projects and all dependencies. That is, it should support the ability to gather up the artifacts for both a hypothetical Exe.csproj and AddonDll.csproj, overlaying the outputs. The Windows Application Packaging project does not support this today and it's a pain point.

I'm a bit confused by this one, I'm fairly aware of how the packaging project works, and this is how I would describe it works. Do you have a repro project or issue to look at?

Sadly it doesn't. If the project isn't executable (exe.csproj in this example), you can't add it as a dependency. Here's a hack @StefanWickDev uses to get around this. (https://stackoverflow.com/questions/48754557/packaging-winforms-application-along-with-native-dll/48772581#48772581) Big pain point for me.

Didn't see any talk about Package.StoreAssociation.xml

I wasn't expecting any difference here, but perhaps it's worth calling that out? Is there something you'd like to see?

Just brought it up for awareness. I suppose an app can continue to target Universal and all this works as-is.

@andrewleader andrewleader added this to the 0.8 (2021 Q2) milestone Mar 30, 2021
@Gavin-Williams
Copy link

Gavin-Williams commented Apr 3, 2021

Desktop and UWP shouldn't be separate project types and runtimes. One of the goals of project reunion should be to correctly unify those two application types. Desktop should be a subset of the Universal application type. Universal apps primarily run on the desktop, it's one of the deployment targets. Desktop is (should be) just a special case of the UWP. The continuation of the idea that Desktop and UWP are separate is an unfortunate result of the misconception even within Microsoft of what UWP is and should be.

UWP could have only survived and also it's only future in whatever form it takes, is as a universal platform across Windows that supports any workload. Any continuation of UWP as a hobbled platform - with forced overlays, with limited deployment, without support and feature growth is a dead-end.

And I know people will hate this idea, because they come from either of two sides of the fence, they either come from the legacy side and refuse to give any oxygen to UWP, it's a mobile platform, it's a containerized and light workload platform. Or they come from the UWP side, it's restricted for a reason, for security reasons or for some other contrived reason and we can't allow it to have any capabilities that break that mould.

This idea actually helps break down the idea that these apps are separate, because really they aren't. When I start a UWP app - I'm 100% intending it to be a desktop app - with security, with Xaml, with WinRT.

@ghost
Copy link

ghost commented Apr 3, 2021

UWP, it's a mobile platform, it's a containerized and light workload platform.

"yes, light, restricted" so much so that instead developing a PWA is waaaaaaaaay much more worthy than this.

since the birth of "UWP", it has always been either you choose the vast win32 developers aka windows developers or you the lose the OS platform business with "little to no UWP" devs.

Let the App Container come to all win32 apps . then "UWP" can RIP forever. thanks.

@Gavin-Williams
Copy link

@ecovio1 Development for UWP is so similar to development for .Net 5 it's just not even an issue. Are you suggesting that if I brought someone on to my team who had no UWP experience, they couldn't handle working on a UWP-Desktop app? That sounds implausible to me. The work is 97% the same between .Net 5 and UWP. I'd imagine Reunion will lift that to 99% or higher. There's practically no distinction between UWP and .Net 5 devs. I would happily take on a .net core / uwp / .net 5 / framework developer in any such position.

The fact that people still think there is such a huge difference, exhibits how confused the situation has been. And moving forward, there is no rule that the UWP security model can't be expended to cover 'win32' needs. The sooner the better. Then we can have a truly universal windows application model.

@andrewleader
Copy link
Contributor

@alwu-msft do we have image assets covered in the spec? Like including images in the single project which get bundled into the msix and used via ms-appx:/// rather than bundled as normal app content? Just thought about that and wanted to make sure that's covered!

@evelynwu-msft
Copy link
Contributor

@andrewleader Not specifically; how image assets are specified and gathered to be included directly in the app package is not being changed, so I don't think there's a need to bring it into the scope of this proposal.

@andrewleader
Copy link
Contributor

@alwu-msft so where will the images be included? The WAP includes image assets as seen below (some are required for core app assets like app icons). Will the Package Action property be available in the single project when package type is set to MSIX?

image

@evelynwu-msft
Copy link
Contributor

They live in the app project just as they do for Universal app projects, and you can set them as Content which will result in them being included in the resources.pri.

@andrewleader
Copy link
Contributor

Awesome. I think that's important information to have in the spec though. Just like understanding how you choose to use MSIX in the project, understanding how you add images is just as important (since that's a new concept for desktop apps, better to not just assume "it'll work" 😊)

Plus, there's probably questions like what happens when you drop a new image into the project, if the project is set to MSIX, will it automatically set the Build Action to Content?

@andrewleader
Copy link
Contributor

andrewleader commented Nov 17, 2021

Single-project MSIX has been shipped in 1.0 today! https://docs.microsoft.com/windows/apps/windows-app-sdk/single-project-msix

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-DeveloperTools Issues related to authoring (source and IDL), debugging, HotReload, LiveVisualTree, VS integration feature proposal
Projects
None yet
Development

No branches or pull requests

7 participants