ant-druha / intellij-powershell

Adds PowerShell language support to IntelliJ-based IDEs.
https://plugins.jetbrains.com/plugin/10249-powershell
Apache License 2.0
70 stars 19 forks source link

Plugin is not correctly detecting Powershell 7 #259

Closed WillemToorenburgh closed 4 months ago

WillemToorenburgh commented 4 months ago
Environment info

Powershell Plugin version: 2.6.0 JetBrains Rider version 2023.3.4 Powershell version: 7.4.1

Hey there!

The issue

The extension seems to fail to detect the version of Powershell 7 I'm using. The language server seemingly never starts up.

The details

I loaded up a Powershell script I'm authoring in Rider with your extension installed, and got some strange syntax highlighting: image (2)

None of the inspections were working, either.

I thought this could be due to a Powershell version mismatch, so I checked the settings for the plugin. Strangely, the executable was the correct one, but the text below said it was version 5.1: image (3)

When I tried changing the executable to powershell.exe the syntax highlighting and analysis worked correctly, though of course it stumbled on any Powershell 6+ features. I checked Process Explorer to see how Rider was executing powershell.exe, and saw it was correctly launching the editor services.

At this point, I uninstalled and reinstalled the plugin, for good measure.

After changing the executable back to pwsh.exe, I checked the spawned pwsh.exe processes and saw a bunch of them: image (4)

They all had this command line invocation:

"C:\Program Files\PowerShell\7\pwsh.exe" -Command "($PSVersionTable.PSVersion, $PSVersionTable.PSEdition) -join ' '"

It's looking like the plugin code is having trouble interpreting the output of the command. I first thought it could be a quoting/interpolation issue, as when I run the same command from within a pwsh.exe shell, it throws an error:

> pwsh.exe -Command "($PSVersionTable.PSVersion, $PSVersionTable.PSEdition) -join ' '"
ParserError: 
Line |                                                                         
   1 |  (System.Management.Automation.PSVersionHashTable.PSVersion, System.Ma …
     |                                                            ~            
     | Missing argument in parameter list.

Converting to single quotes on the outside and double quotes in the -join fixed this when I ran it in pwsh.exe and I tried poking around in your source to see if I could make that change and test it locally. However, I've never developed anything in Kotlin before and know nothing of the ecosystem. The learning curve is sadly a bit too steep for me to just pick it up and go.

However it's likely that's not the issue anyhow, as the command as originally formatted works fine when run through cmd.exe, and, I assume, through the GeneralCommandLine method. I did notice that the GeneralCommandLine arguments include -NoProfile, while what's getting executed on my machine does not. Not sure what this means, honestly, seeing as I've got the latest version of the plugin installed.

ForNeVeR commented 4 months ago

Oh, that is a very interesting story, and there's quite a bit to unpack here.

First thing, -NoProfile is merged but the version with this is not yet released. I wonder if there's something in your profile that may be spoiling things for us. We'll see about that.

The whole endeavor I assume could be connected with #79, and, through that, to https://github.com/PowerShell/PowerShell/issues/11747 (a long-standing issue I recently fixed myself in PowerShell — the fixed version is also not yet released).

When you run pwsh.exe via PowerShell, you are supposed to escape the $ sign, like this:

> pwsh.exe -Command "(`$PSVersionTable.PSVersion, `$PSVersionTable.PSEdition) -join ' '"

Otherwise, it will interpolate $PSVersionTable and I guess nothing good will come from that. So, this part I understand.

But then, it is not yet clear what happens with the process output. Maybe stderr is blocked or something?

I digress and let's get to the point, though.

  1. First of all, how do you install PowerShell?

    Also, are you absolutely sure the plugin runs "C:\Program Files\PowerShell\7\pwsh.exe" and not a binary from some other place, such as dotnet tool or something else?

  2. I think the screenshot is from Process Explorer, so, just as a sanity check, could you please show a full screenshot of the tooltip with the process command line?

  3. Could you please run the following command from cmd (important: from cmd!)?

    pwsh.exe -Command "($PSVersionTable.PSVersion, $PSVersionTable.PSEdition) -join ' '" > out.txt

    And then show the output of this command (if there's any output whatsoever) and the contents of out.txt?

    The very presence of any output could hint us at what's going on.

WillemToorenburgh commented 4 months ago

Thanks for the response!

My bad, I should have been checking the code at the release tag 😅

  1. How I install Powershell: choco! I run choco install pwsh in an elevated powershell.exe prompt
  2. That's right! Here's a screenshot. Sorry I didn't capture it this way before; had to source an alternative method of screenshotting as Snip & Sketch refused to capture the tooltip. image
  3. Sure thing. I tried running it before, which I mention in my last paragraph, but it occurs to me that I entered cmd.exe from a pwsh.exe shell, which could have messed things up. Here's the run from cmd.exe:
    >pwsh.exe -Command "($PSVersionTable.PSVersion, $PSVersionTable.PSEdition) -join ' '" > out.txt

    ...which gave no output to the terminal. However, the out.txt is very interesting:

    Import-Module: C:\Users\willem.toorenburgh\Documents\PowerShell\profile.ps1:23
    Line |
      23 |  Import-Module "C:\Program Files\PowerToys\WinUI3Apps\..\WinGetCommand .
         |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         | Could not load file or assembly 'PowerToys.CmdNotFound, Version=0.78.0.0, Culture=neutral, PublicKeyToken=null'.
    Set-PSReadLineOption: C:\Users\willem.toorenburgh\Documents\PowerShell\profile.ps1:49
    Line |
      49 |  Set-PSReadLineOption -PredictionSource HistoryAndPlugin
         |  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
         | The predictive suggestion feature cannot be enabled because the console output doesn't support virtual terminal
         | processing or it's redirected.
    7.4.0 Core

    Looks like your suspicion is right, it's my profile. The culprits are PowerToys CommandNotFound and Set-PSReadLineOption -PredictionSource HistoryAndPlugin. Speaking of which, you can see exactly what I use, as I commit it to Github for portability: https://github.com/WillemToorenburgh/pwsh-profile/blob/main/profile.ps1

I put it into $PROFILE.CurrentUserAllHosts as I don't want to have to duplicate my profile across >4 different shell hosts, and it seems like the pwsh.exe spawned by Rider is included.

If I modify the command to be

pwsh.exe -NoProfile -NonInteractive -Command "($PSVersionTable.PSVersion, $PSVersionTable.PSEdition) -join ' '" > out.txt

then the output is as expected: 7.4.0 Core.

Looks like your merged -NoProfile is enough to be a fix! You could consider adding -NonInteractive for extra safety, but I imagine -NoProfile should be plenty. Thanks for the help!

ForNeVeR commented 4 months ago

Thanks for your response. -NonInteractive is a good option as well, I'll add it.