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
"Loading" of Windows Runtime assemblies fails in 7.1 Preview 4 #13042
Comments
This is due to removal of builtin support in dotnet, see dotnet/runtime#37672. /cc @SteveL-MSFT while this breaking change isn't PowerShell's fault, it will have a decent impact. It may be a good idea to look into adding built in support. C#/WinRT package seems to be the recommendation, though at a glance it doesn't look like that can be used as a general solution. There are some very popular modules that utilize winrt APIs (like BurntToast by @Windos). |
It may be that my morning coffee is only half drunk atm, but I'm struggling to wrap my head around making use of C#/WinRT in (non-C#) PowerShell. From what I can see on the Gallery, the biggest use case of these WinRT assemblies are Toast Notifications of various flavours (Even dbatools uses them). If we could wrangle built-in support in PowerShell that'd be super 💜. If not, it looks like module authors will need to figure out runtime projection... in BurntToast's case that'll probably mean a version or two that caps its host support at 7.0 until I/someone figure it out. |
PowerShell has never WinRT support. The fact that users could load WinRT assemblies previously does not mean that everything worked out of the box. Moreover, the engine explicitly blocks WinRT event processing (Also it seems the engine consider WinRT types as special case). |
@iSazonov I 100% agree that this break isn't PowerShell's fault or even necessarily it's responsibility to fix. It still might be a good idea though.
In the same way it never supported
It also blocks processing of event handlers with a return type other than |
Technically we would need to reference C # / WinRT package. But now the package is not ready for release. Also I guess MSFT team prefer to reduce PowerShell distributive size. |
@Windos If I understand correctly BurntToast doesn't work on latest PowerShell preview. Do you consider C # / WinRT package for BurntToast? |
@iSazonov Yeah, BurntToast 100% relies on WinRT assemblies so this change in .NET will break the module in PS preview. I missed Preview 4 before the MSI got pulled, so will confirm this when Preview 5 is out. I will be looking into C#/WinRT, but haven't had a chance to sit down and figure that out yet. |
@Windos You can load a nightly build from main page of the repo. |
Another use case of WinRT assemblies that's worth to be considered are its bitmap decoders that support Apple's HEIF format. I'm not aware of any alternative provided by Microsoft. |
I'll bring this up with the .NET team |
With the breaking change in .NET5 Preview 6, https://devblogs.microsoft.com/dotnet/announcing-net-5-0-preview-6/, you will now need to reference a cswinrt generated interop assembly to call winrt apis. For the Windows WinRT apis, we've built a nuget package that provides this support, and will need to be referenced when building the module - https://www.nuget.org/packages/Microsoft.Windows.SDK.NET
|
There are three big questions we need to answer:
|
Modules referencing a nuget dependency is a scenario that still does not work anything close to well and isn't a supported scenario for PowerShellGet as far as I'm aware. Not sure if that's planned to change for v3 of that module but it really should if it hasn't already. Until that's working seamlessly things like this will need to be included in PowerShell itself to avoid breaking changes. |
Workaround:
Add-Type -AssemblyName In BurntToast, remove lines like 2137 that try to load the types using fully qualified names as those types are projected from different assemblies. Was able to get I'd like to get PowerShellGetv3 to manage nuget.org dependencies but until that exists you'll have to pkg your module with those assemblies and load them. |
I see a size of latest version of microsoft.windows.cswinrt package is ~977 Kb. We could add it in PowerShell 7.1 distribution until PowerShellGet addresses dependencies. |
That was unbelievably easy, thanks for spelling out the work around @SteveL-MSFT! Also, this whole thing also addresses #2181 as the reflection includes event handling and... that works now: n.b. that last statement applies only to 7.1 |
Will have PS-Committee review whether we should just include the necessary assemblies with PS7.1 |
Is that a community call review (and does that mean I'll have to wake up for the next call 😂)? |
@Windos no, the PS-Committee is separate from the Monthly Community Calls. PS-Committee meets twice a week to weigh in on certain decisions affecting PowerShell |
@PowerShell/powershell-committee reviewed this, we agreed that we will not be redistributing the WinRT assemblies with PowerShell 7.1. We also agreed to have documentation added to help PowerShell users that want to use WinRT. |
More generally, we also agreed that we should, as a rule, snap to .NET's decision on API surface area except where there is overwhelming evidence that something has additional value to PS users. E.g. WinForms/WPF are used heavily in the PS ecosystem, and make sense to continue including on Windows. |
Thanks for the quick decision on this. Will work on a module update to include the assemblies. |
/cc @sdwheeler for reference. |
Based on this thread I've been able to successfully use some WinRT classes in PowerShell by importing the two dlls in this BurntToast folder, but I can't figure out how to get or build these dlls from the primary source. Are these on NuGet somewhere?
I'm attempting to update this library: https://github.com/rkeithhill/PoshWinRT which is a C# wrapper that can be imported in PowerShell in order to use APIs that use Async file operations. |
@xdhmoore: https://www.nuget.org/packages/Microsoft.Windows.SDK.NET.Ref/
|
This issue has been marked as by-design and has not had any activity for 1 day. It has been closed for housekeeping purposes. |
Must load Types from Assemblies See PowerShell/PowerShell#13042
You can now fix this with the Import-Package module that I just published to PowerShell gallery. Import-Package "microsoft.windows.sdk.net.ref" It automatically installs (if not already installed) the Microsoft.Windows.SDK.NET.Ref package and imports the whole .nupkg into the PowerShell session. Small warning though: That Microsoft package does not make use of the NuGet "runtime" directory, so Import-Package will not know that this package is Windows-specific, and will try to import it, even if you are running it from PowerShell on Linux. |
I am sorry, but can someone please explain to non-programmers how to take advantage of this fix (or some other workaround)? I do not know anything about assemblies, namespaces, runtimes, etc. In my heart, I'm a mere sysadmin writing my 10-20 lines scripts that sometimes need to tackle Windows APIs, and historically PowerShell has been exceptionally good in that. E.g., considering the basic examples in the very first message in this thread (or slighly more complex code samples like this), what exactly needs to be changed so that they work in PS7? (And, preferably, still work in PS5.1). And I apologize if this has been already documented. Unfortunately, Internet search for "winRT PowerShell" currently gives you this thread as the most relevant link and not some documentation page. |
@sdwheeler Have we the docs or a doc issue? |
@iSazonov No we don't have docs or a docs issue. Please open a docs issue and provide the necessary information needed for the docs. |
I created doc issue but don't have specific information for this documentation. I hope the participants in this discussion will post steps for using WinRT there. |
You can actually just run whatever code on the older PowerShell by wrapping stuff with eg As a simple example. You can open PowerShell and run any PS version by typing the name for it eg in PS 5.1.x I can type pwsh in my instance: > Might as well also add that you can check PS version or whatever else in the scripts and have the scripts interact with multiple PS versions (I added some version example above that could be the start of that. match would need to be changed to a better means of matching). Just search the internet how to do it. I'm sure there's multiple things as I can come up with 2 ways at least in my head. If you have an error like in OP, and an older installed PS version where it works, then you can do this as long as there's an old enough installed PS version available. You just need to figure out where to wrap your scripts or code to work best. To me that is simpler and better than doing anything above and I use it but it depends on your situation (and opinion). I can't help you further on this. Just giving a hint of something possible that you can do and adding another possibility here to deal with the issue =) |
Steps to reproduce
[void][Windows.Storage.StorageFile, Windows.Storage, ContentType=WindowsRuntime]
[void][Windows.Graphics.Imaging.BitmapDecoder, Windows.Graphics, ContentType=WindowsRuntime]
Expected behavior
WinRT assemblies are loaded.
Actual behavior
InvalidOperation: Unable to find type [Windows.Storage.StorageFile,Windows.Storage, ContentType=WindowsRuntime].
InvalidOperation: Unable to find type [Windows.Graphics.Imaging.BitmapDecoder,Windows.Graphics, ContentType=WindowsRuntime].
Environment data
PSVersion 7.1.0-preview.4
PSEdition Core
GitCommitId 7.1.0-preview.4
OS Microsoft Windows 10.0.18363
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
The text was updated successfully, but these errors were encountered: