-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Use embedded CsWinRT #5178
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
Use embedded CsWinRT #5178
Conversation
Windows.Data; | ||
Windows.Devices; | ||
Windows.Foundation; | ||
Windows.Gaming; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity - why do we need Windows.Gaming
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It appears to be in the closure of things we need. The list was generated by iteratively building and adding namespaces until the unrecognized namespace/type errors stopped. It is possible that a more targeted set of types could be determined to prevent quite so much from being generated.
I will give that a try to see if it isn't too painful, as it will reduce build time and potentially allow us to not need to set up trimming.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, very painful.
I did however try removing just Windows.Gaming
and found that it was Windows.UI.Input.Preview.Injection
that was pulling it in. Since we can selectively exclude things, this pruning seems like a more sane way to get rid of some of the excess.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, 25% reduction isn't too bad for just trimming off one small portion. Thanks!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the same optimization apply to Engine, or is that one more painful?
Windows.Management; | ||
Windows.Media; | ||
Windows.Networking; | ||
Windows.Perception; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the same line as @Trenly's comment, could we do without the Windows.Perception namespace, and maybe Windows.Graphics?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In terms of size reduction, I am assuming that generated code file size translates linearly to resulting binary size. The Xaml file(s) were drastically larger than any other, so its removal resulted in the largest drop. The remaining namespaces are all a more gradual size gradient. The largest ones would result in ~500 KB each if linear (current size is ~24 MB, which is already a size savings over the SDK assembly we get to leave out).
I tried removing some of them, but it takes around a minute to iterate and there are some things in each of these namespaces that are required. The best thing someone could do would be to write code to analyze the SDK use of a non-embedded build, then output the list of types needed. Presumably a huge list of types would be faster and a perfect pruning for output size.
#if WinGetCsWinRTEmbedded | ||
internal sealed class PowerShellConfigurationSetProcessorFactory : IConfigurationSetProcessorFactory, IPowerShellConfigurationProcessorFactoryProperties, IPwshConfigurationSetProcessorFactoryProperties | ||
#else | ||
public sealed class PowerShellConfigurationSetProcessorFactory : IConfigurationSetProcessorFactory, IPowerShellConfigurationProcessorFactoryProperties, IPwshConfigurationSetProcessorFactoryProperties | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: This may be worse but if the access modifier is the only thing that changes, could we have only that be conditional? Not sure if C# would allow it
#if WinGetCsWinRTEmbedded
internal
#else
public
#endif
sealed class PowerShellConfigurationSetProcessorFactory : IConfigurationSetProcessorFactory, IPowerShellConfigurationProcessorFactoryProperties, IPwshConfigurationSetProcessorFactoryProperties
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.1.6" /> | ||
</ItemGroup> | ||
|
||
<Import Project="..\..\targets\ReferenceEmbeddedCsWinRTProject.targets" /> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I assume none of these are affected when the Processor is not using Embedded?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The only use case for that build is the nuget; these projects are not intended to ever ship with it after the merge.
This comment was marked as outdated.
This comment was marked as outdated.
I took another run at building up the types required and was able to get the output down to 2.7 MB (and build time to a few seconds rather than a minute. Some lessons:
But given the massive build time and binary size savings it seems to be worth the effort. [Edit] Also, this and other measures may be required as the last build failed due to running out of disk space :( |
Windows.Perception; | ||
Windows.Security; | ||
Windows.Services; | ||
Windows.Globalization.DayOfWee; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I love this. It sounds so festive to me. "Day of weeeeee~"
But brits may disagree with my interpretation 😆
</PropertyGroup> | ||
|
||
<PropertyGroup Condition="'$(TargetFramework)' == '$(DesktopFramework)'"> | ||
<LangVersion>10</LangVersion> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the move from global to DesktopFramework only intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, as the embedded code requires a higher version.
## Issue Updating the version of CsWinRT that we use lead to a problem with conflicting WinRT.Runtime assemblies (microsoft/winget-dsc#140). While that issue was mitigated by delisting the offending version, in order to ship any release with the newer version of CsWinRT, we need to embed the WinRT.Runtime in our assemblies. ## Change Move to use embedded CsWinRT, specifically in `Microsoft.WinGet.Client.Engine` and `Microsoft.Management.Configuration.Processor`. The dependent projects are updated to no longer reference CsWinRT, but requires some special handling to prevent errors. Since the configuration code was leveraging a projection assembly, it is being replaced by the processor. The projected types are shared out to those dependent binaries via `InternalsVisibleTo`. Also fixes an annoying behavior where an exception escaping from a command execution would prevent the `--logs` option from opening the log location (error cases being more likely to be the time one would want the logs of course).
Issue
Updating the version of CsWinRT that we use lead to a problem with conflicting WinRT.Runtime assemblies (microsoft/winget-dsc#140). While that issue was mitigated by delisting the offending version, in order to ship any release with the newer version of CsWinRT, we need to embed the WinRT.Runtime in our assemblies.
Change
Move to use embedded CsWinRT, specifically in
Microsoft.WinGet.Client.Engine
andMicrosoft.Management.Configuration.Processor
. The dependent projects are updated to no longer reference CsWinRT, but requires some special handling to prevent errors.Since the configuration code was leveraging a projection assembly, it is being replaced by the processor. The projected types are shared out to those dependent binaries via
InternalsVisibleTo
.Also fixes an annoying behavior where an exception escaping from a command execution would prevent the
--logs
option from opening the log location (error cases being more likely to be the time one would want the logs of course).Validation
Minor local validation that things work. Build regression tests will be the true test.
Microsoft Reviewers: Open in CodeFlow