-
Notifications
You must be signed in to change notification settings - Fork 406
Description
Proposal: Address Project Reunion goals by addressing Visual Studio restrictions
Summary
Many of the barriers to code sharing and interop that Project Reunion seeks to remove are either active restrictions, or passive limitations, of Visual Studio. These have been surfaced with the release of new WinRT projections like C++/WinRT and C#/WinRT.
Rationale
Project Reunion is likely to highlight these Visual Studio restrictions even more, and so should address their elimination. These restrictions fall into build time and run time categories, detailed below. This proposal is something of a grab bag of known issues, and seeks to prioritize their resolution so that the end to end developer experience is more streamlined.
Build Time
C++ PackageReferences
C++ projects (*.vcxproj files) do not support Nuget PackageReferences, but only packages.config references, which have a number of limitations:
- They must target a specific package version, even with allowedVersions
- They don't participate with the project system, so can't import other artifacts or use replaceable parameters
- They don't support 'msbuild /t:restore', so a separate 'nuget restore' is necessary in build pipelines, etc
There is a longstanding open request to add this support:
Use PackageReference in vcxproj
And a related longstanding open PR to implement it:
add C++ PackageReference support
Desktop <--> UWP Project References
Project references cannot be added in Visual Studio between Desktop and UWP (Universal Windows) projects. Attempts to do so result in an error: A reference cannot be added because the two projects target different platforms.. This can be worked around with a project file edit, or introduction of a directory.build.* file, to manually add the project reference. In other words, this is strictly a tooling restriction, which prevents interop unless developers are aware of the workarounds.
Runtime
Unified CRT
Having enabled Desktop<-->UWP project references, the developer must then address the runtime conflict of C Runtime libraries used by both modules. A Desktop module imports C:\Windows\System32\vcruntime140.dll and friends, while a UWP module imports C:\Program Files\WindowsApps\Microsoft.VCLibs.140*\vcruntime140_app.dll and friends. This impedance mismatch can be addressed by using the VCRT Forwarders package. But this technique is not very discoverable (it's not obvious that CRT dynalink errors can be addressed with a special adapter Nuget package).
A better solution is the inclusion of both CRT flavors in a unified VCLibs.UWPDesktop framework package, usable by both packaged UWP and centennial modules. This would obsolete the need for the VCRT Forwarders package, which is an explicit user action that adds build and deploy complexity, and increases install image size. Visual Studio could ensure that all binaries are "chameleon linked" with the CRT, using the Desktop import entries. Selection between Desktop CRT and unified VCLibs framework package could then be deferred until runtime, enabling broad reusability of modules. Visual Studio could also automatically select the unified VCLibs framework package for debugging and packaging behavior of UWP projects.
Native WinRT Activation
Having addressed the CRT linkage issues, there are often WinRT activation issues. Historically, activation of user-defined WinRT components was restricted to packaged apps. With Windows 1903 (19H1), support was added for unpackaged app activation, based on a fusion manifest: Enhancing Non-packaged Desktop Apps using Windows Runtime Components. This requires additional user action that is not discoverable and is tedious - the manifest requires an entry for every activatable class. Visual Studio could include project templates and/or build-time customization to automatically generate and populate this manifest.
There is an effort to address the Windows 1903 requirement of the Reg-Free Activation feature above, using a Detours-based library: Undocked RegFree Winrt Activation. Ideally, this library could be delivered as a Nuget package, along with build-time customizations mentioned above, and included in Visual Studio project templates.
Managed WinRT Activation
The above discussion addresses activation of native components, from either native or managed code. There is some support in Visual Studio for the opposite - activating managed components from native code. But this is subject to a number of limitations.
For example, a packaged UWP app can include a project reference to a managed UWP component and Visual Studio will generate the necessary uwpshims.exe appx manifest entry for hosting the managed component. However, there is a bug in this support that requires targeting Windows SDK 15063 (RS2) or older: Enable C++ Hybrid apps to target .Net native 1.7 and 2.2 without workarounds.
For activating a managed component from a native Desktop (non-packaged) app, there is currently no support in Visual Studio. An approach similar to Reg-Free Activation above (using a fusion manifest, in the absence of any other app manifest), could be used to implement shim support similar to that for packaged apps above.