interactive
interactive copied to clipboard
Out-Gridview in .NET (PowerShell) kernel fails
Hello
Describe the bug
When I try to use Out-Gridview in a code cell of a notebook with .NET (PowerShell) kernel it fails.
Is there any way to use Out-Gridview in a code cell when the notebook kernel is .NET (PowerShell)? I use Out-GridView a lot as a selection tool when the kernel is PowerShell and would like to be able to do it also with .NET (PowerShell). Not being able to do it is something that stops me from adopting the latter.
The problem exists in Azure Data Studio, Jupyter Notebook and VSCode. For more info see: Notebook, Out-Gridview in .NET (PowerShell) kernel fails #17105
In case it is not currently possible, will you be able to advise me where to make the request?
Regards
Please complete the following:
Which version of .NET Interactive are you using? (In a notebook, run the #!about magic command. ):
1.0.255902+b0afbdc47dec91e62b0c5cb587a0f2c24242eca8
- OS
- [ ] Windows 11
- [x] Windows 10
- [x] Windows Server 2022
- [ ] macOS
- [ ] Linux (Please specify distro)
- [ ] iOS
- [ ] Android
- Browser
- [ ] Chrome
- [ ] Edge
- [ ] Firefox
- [ ] Safari
- Frontend
- [x] Jupyter Notebook
- [ ] Jupyter Lab
- [ ] nteract
- [x] Visual Studio Code
- [ ] Visual Studio Code Insiders
- [ ] Visual Studio
- [x] Other (please specify) Azure Data Studio
Screenshots
Out-GridView launches an external window so it won't work but give this should:
$processes = Get-Process
$processes | Select Name, Id | Out-Default
Hello @jonsequitur
Apologies for not having detected your response earlier, being an issue of November 2021 I had already resigned myself to the fact that it would remain unsolved.
Unfortunately your suggestion does not work for me.
As I mentioned initially, I want to use Out-GridView as a selection tool inside a PowerShell (.Net Interactive) cell within a notebook.
No offense intended, I ask you to please re-read my initial post.
It seems to me that as it works now ".Net Interactive" is not very interactive. In fact the PowerShell (Jupyter kernel) does allow you to use Out-GridView in the way I want.
Can you think of a way in which I can achieve the interactivity that Out-GridView provides in other contexts when used with the -OutputMode parameter as Single or Multiple ?
An example of what I want to do is:
$processes = Get-Process
$processesToStop = $processes = $processes | Out-GridView -OutputMode Multiple #Here I select the processes to kill
$processesToStop | Stop-Process
Best regards, Claudio Salvio
@daxian-dbw Any insights here?
In fact the PowerShell (Jupyter kernel) does allow you to use Out-GridView in the way I want.
@claudio-salvio Can you point me to this kernel and/or provide an example of what the experience looks like when it works as you would like?
@jonsequitur
Thank you for your prompt reply.
In September 2021, I started the search for a solution to this issue in the Azure Data Studio forum with the issue Notebook, Out-Gridview in .NET (PowerShell) kernel fails #17105 .
Based on the discussion there, I considered the problem to be related to Dotnet Interactive and registered this issue here in November 2021.
Attached is more info regarding the issue obtained using Azure Data Studio (ADS).
In ADS, with the PowerShell kernel (Jupyter Python based) the cell runs normally.
The Out-GridView window appears, I can select rows and the $processesToStop variable is assigned with the selected processes.

In ADS, with the PowerShell kernel (.NET Interactive) the cell execution gives an error when running: "Out-GridView: Exception has been thrown by the target of an invocation.".
The Out-GridView window does not appear and -as expected in this case- $processesToStop is set to null since no selection has been made.

In Visual Studio Code, with the PowerShell kernel (.NET Interactive) something different happens: the cell keeps running endlessly and the Stop button does not work to stop the execution. To interrupt it, it is necessary to close the VSCode window.

Let me know if you need any other information.
Best regards, Claudio Salvio
I'm afraid Out-GridView won't work in .NET Interactive because it depends on WPF. For PowerShell Core, When building package for Windows, we use Microsoft.NET.Sdk.WindowsDesktop instead of Microsoft.NET.Sdk to include the WPF components, and that's why Out-GridView works in PowerShell Core on Windows. .NET Interactive doesn't have WPF components included, so it won't work. Also, WPF application requires STA thread apartment.
For the PowerShell kernel (Jupyter Python based), it actually has a fully fledged Windows PowerShell process running behind the scene, and that's why Out-GridView works there.
Thanks, Dongbo! Is there an alternative approach you can think of that would work for this? Is there a module that could be loaded at runtime that might enable this?
Hello @daxian-dbw
Regarding your comment:
"I'm afraid
Out-GridViewwon't work in .NET Interactive because it depends on WPF. For PowerShell Core, When building package for Windows, we useMicrosoft.NET.Sdk.WindowsDesktopinstead ofMicrosoft.NET.Sdkto include the WPF components, and that's whyOut-GridViewworks in PowerShell Core on Windows."
it would seem that the most obvious solution is for .Net Interactive to also use Microsoft.NET.Sdk.WindowsDesktop.
Is there any obstacle for that to happen?
I consider that in "literate programming" it is very necessary to have interaction mechanisms such as the one offered by Out-GridView.
In my personal case, since a couple of years ago, I work with notebooks almost every day. Because of the way I use them, I usually need to select items from lists and other types of tasks that involve real interactivity.
I raised an issue regarding Out-GridView because it is by far the most necessary for me in this aspect but I understand that this problem is not limited to this function.
It also affects other very useful and interactive features such as Show-Command.
As the support for notebooks with PowerShell .NET Interactive kernel was improved I was trying to adopt it but the lack of interactivity is a big obstacle.
Can you think of any other alternative to enjoy the required functionality?
Regards Claudio Salvio
I agree that this kind of interactivity is important. We'd like to support it in a way that's truly cross-platform so that notebooks can be shared across operating systems as well as in browser-based online editors like CodeSpaces, so the Windows-specific implementation is the main reason this implementation isn't supported.
We're very open to proposals.
Is there an alternative approach you can think of that would work for this? Is there a module that could be loaded at runtime that might enable this?
No such module exists today, but potentially it may be possible to have a module (or a nuget package?) that contains all the necessary WPF assemblies. It would also require running in STA though.
@daxian-dbw, @jonsequitur
No such module exists today, but potentially it may be possible to have a module (or a nuget package?) that contains all the necessary WPF assemblies.
It seems to me that it would be a very positive thing if we could have a solution in the short term, even if it is specific to Windows, until a multiplatform solution is generated.
The faithful users of Windows (in my case user of Microsoft products since MSDOS 3.x) sometimes we feel that this initiative of your company by the multiplatformity hurts us because there are cases in which it is leveled down using the logic this is multiplatform or nothing.
I find the goal of cross-platform laudable as long as it does not mean that the many millions of Windows users lose functionality that can be achieved with relative ease in our operating system.
Hopefully in this case we can move forward with something Windows-specific (as with Out-GridView in PowerShell 7.x) until the platform-independent solution is available.
It would also require running in STA though.
Honestly I am not concerned in the least for the type of work being done in these cases.
Best regards, Claudio Salvio
@jonsequitur, @daxian-dbw
I had forgotten to mention another very useful command to perform authentications when using notebooks that also does not work in the PowerShell (.Net Interactive) kernel but it does in the PowerShell kernel (Python based): Get-Credential.
How can I replace its use in the current state of the PowerShell (.Net Interactive) kernel ?
I mean replace it without doing questionable practices like putting passwords in environment variables.
I think it is pertinent to mention that I am a user of the Secret Management module and I use it whenever I can.
Claudio Salvio
Get-Credential command was changed in PowerShell Core to not use the pop-up windows, but instead provides the console experience:

In .NET Interactive Jupyter Notebook, it works as the follows:

This would be a tough choice - I love the multi-language ability here, especially with SQL and variable sharing but out-gridview is a vital selector tool...
Is there a way to load WPF dlls in the same way one loads other windows system dlls in powershell? The requirement to run such notebooks on widows is not a limitation in our environment.
You can load a DLL in a C# or F# shell using #r:
#r "/path/to/assembly.dll"
But would dlls loaded in c# be available in powershell? Since the are in different kernels It doesn't seem likely unless you can instantiate an object, share it to powershell and use it from there? And then how much work to get an out-gridview like functionality?
It would be a pain to switch languages to get user input.
On Tue, 21 Feb 2023, 17:56 Jon Sequeira, @.***> wrote:
You can load a DLL in a C# or F# shell using #r:
#r "/path/to/assembly.dll"
— Reply to this email directly, view it on GitHub https://github.com/dotnet/interactive/issues/1792#issuecomment-1438808637, or unsubscribe https://github.com/notifications/unsubscribe-auth/ADRXBSBPVFLI3BSMCUZRRWTWYTXVNANCNFSM5I266TJQ . You are receiving this because you commented.Message ID: @.***>
I misunderstood. You don't need to switch languages here, and the assembly loaded into C# will not be available in PowerShell.
Loading WPF assemblies in PowerShell might work. I'm not sure. Assuming it does, just be aware that the solution won't work with remote subkernels or on non-Windows machines.
I was trying to recreate out-gridview functionality but can't get loading of a wpf assembly to work in polyglot. The code below works in the powershell ISE but nothing appears to happen in the notebook.
[void][System.Reflection.Assembly]::LoadWithPartialName('PresentationFramework')
function Out-Grid ($properties, $context_menu_items)
{
$dataGrid = New-Object -TypeName System.Windows.Controls.DataGrid -Property @{
IsReadOnly = $true
AutoGenerateColumns = $true
}
$dataGrid.ItemsSource = @($input)
$grid = New-Object System.Windows.Controls.Grid
$grid.Children.Add($dataGrid) | Out-Null
$window = New-Object System.Windows.Window -Property @{ Content = $grid }
$window.ShowDialog() | Out-Null
$dataGrid.SelectedItem
}
dir | Out-Grid
As I mentioned in https://github.com/dotnet/interactive/issues/1792#issuecomment-1107058569, running WPF requires the thread is in the STA thread apartment, and it will fail otherwise. However, the .NET Interactive is running in MTA I believe.
I was just experimenting a little with running this in a new thread in a notebook and setting the apartment state. It looks like there are some missing dependencies that might be specific to my machine. I'm not familiar enough with Out-GridView to know. I'm not sure if it's useful but here's what I did:
using System.Threading;
using Microsoft.DotNet.Interactive;
using Microsoft.DotNet.Interactive.Commands;
var newThread = new Thread(new ThreadStart(ThreadMethod));
newThread.SetApartmentState(ApartmentState.STA);
newThread.Start();
newThread.Join();
static void ThreadMethod()
{
Console.WriteLine("ThreadMethod starting");
var powershellCode = """
[void][System.Reflection.Assembly]::LoadWithPartialName('PresentationFramework')
function Out-Grid ($properties, $context_menu_items)
{
$dataGrid = New-Object -TypeName System.Windows.Controls.DataGrid -Property @{
IsReadOnly = $true
AutoGenerateColumns = $true
}
$dataGrid.ItemsSource = @($input)
$grid = New-Object System.Windows.Controls.Grid
$grid.Children.Add($dataGrid) | Out-Null
$window = New-Object System.Windows.Window -Property @{ Content = $grid }
$window.ShowDialog() | Out-Null
$dataGrid.SelectedItem
}
dir | Out-Grid
""";
try
{
var result = Kernel.Root.FindKernelByName("pwsh").SendAsync(new SubmitCode(powershellCode)).GetAwaiter().GetResult();
result.Display();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
}
Here's the result I saw when I ran it: