Skip to content

Support PowerShell v3 and v4 #73

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

Closed
daviwil opened this issue Dec 12, 2015 · 18 comments
Closed

Support PowerShell v3 and v4 #73

daviwil opened this issue Dec 12, 2015 · 18 comments
Labels
Issue-Enhancement A feature request (enhancement).
Milestone

Comments

@daviwil
Copy link
Contributor

daviwil commented Dec 12, 2015

Currently we support only PowerShell v5 but it wouldn't take a great deal of effort to support PowerShell 3 and 4. PoshTools has accomplished this already so there's some work there to be learned from.

The newly released PowerShell reference assemblies could help build version-specific implementation DLLs: http://blogs.msdn.com/b/powershell/archive/2015/12/12/powershell-sdk-reference-assemblies-available-via-nuget-org.aspx

@daviwil daviwil added the Issue-Enhancement A feature request (enhancement). label Dec 12, 2015
@daviwil daviwil changed the title Support PowerShell 3, 4, and 5 Support PowerShell v3 and v4 Dec 12, 2015
@adamdriscoll
Copy link
Contributor

I'm curious your thoughts on how this will be accomplished. In PoshTools, it really isn't doing anything with S.M.A.dlls. It's more lucky that the assembly version didn't change and we do some checking to prevent MissingMethodExceptions. I think this will eventually lead to a problem if the version does change so it would be good to figure out a way to accomplish it correctly.

One thing that is done via AppVeyor is to build 2013 and 2015 extensions. This is done using some custom MSBuild targets\props.

Are you thinking that we would have different project files or do something similar with custom MSBuild targets? I think the latter would keep the VS solution tidy but is a little more work. The one thing I'm a bit unclear about would be the packages.config file. It seems like we'd need a separate one for each build type or have it patched before package restore kicks in.

I'm sure I'm just totally overthinking this. :)

@daviwil
Copy link
Contributor Author

daviwil commented Dec 31, 2015

The way you've done it is probably the best way to do it for now. For PowerShell v3 through v5 we can probably use the same implementation DLL. If for some reason we have a different SMA assembly version in the future which breaks compatibility with previous code contracts, we'll need to have a different core logic assembly for Editor Services that we hide behind a well-defined interface.

Here's a potential design:

  • Microsoft.PowerShell.EditorServices.dll shifts from providing implementations for all features to defining the core feature interfaces that the Editor Services library exposes. It would also provide the library 'lifetime' code that simplifies the use of feature implementations for any version. The caller would specify which implementation assembly to use when they create a new EditorSession.
  • Introduce Microsoft.PowerShell.EditorServices.v345.dll which contains the feature implementations that were previously found in the core DLL.
  • There could potentially be some 'common' DLL that could share any feature implementations that are version-independent but I'm not sure how likely (or easy) that will be. This would be used as a dependency to every version-specific implementation assembly.
  • The Microsoft.PowerShell.EditorServices.Host.exe project would add a new parameter which allows the caller to specify the path to an implementation DLL to use. This would allow a host to be shipped with multiple implementation DLLs that can be selected by the user on a per-session basis.

I don't think we need to go down this road until it's totally necessary, though. For now it's probably more than sufficient to take a similar approach to PoshTools and just be tolerant of whatever PS version is present.

One place where this might become necessary is with PowerShell running on Nano Server. Pretty soon I'll try to convert the codebase over to the new project.json system so that we can build for both full .NET and CoreCLR. I suspect we may have to deal with some interface differences there, but I'm not entirely sure yet.

Let me know what you think!

@daviwil daviwil modified the milestone: Backlog Dec 31, 2015
@daviwil daviwil modified the milestones: 0.4.0, Backlog Jan 4, 2016
@daviwil
Copy link
Contributor Author

daviwil commented Jan 4, 2016

Adam's PR has solved this by making sure we can compile correctly against the v3 and v4 PowerShell reference assemblies.

One last thing needs to happen before we can smoothly support the lower versions: adopt the next PSScriptAnalyzer release which includes PowerShell v3 support.

@daviwil
Copy link
Contributor Author

daviwil commented Jan 4, 2016

Sweet, AppVeyor 2.0 beta supports a build matrix:

http://www.appveyor.com/beta

I'm trying to see what it will take to get the PowerShell account moved over to that so we can do test runs for both PowerShell v3 and v5 :)

@adamdriscoll
Copy link
Contributor

That would be awesome! That is something I always wanted to do with PoshTools. It's great that AppVeyor supports that now!

@daviwil
Copy link
Contributor Author

daviwil commented Feb 8, 2016

Just tried the latest PowerShell Editor Services on a machine with PowerShell v3 and it crashes immediately with a MissingMethodException:

Unhandled Exception: System.MissingMethodException: Method not found: 'Void System.Management.Automation.Debugger.SetDebugMode(System.Management.Automation.DebugModes)'.
   at Microsoft.PowerShell.EditorServices.PowerShellContext.Initialize(Runspace initialRunspace)
   at Microsoft.PowerShell.EditorServices.PowerShellContext..ctor()
   at Microsoft.PowerShell.EditorServices.EditorSession.StartSession()
   at Microsoft.PowerShell.EditorServices.Protocol.Server.LanguageServer..ctor(ChannelBase serverChannel)
   at Microsoft.PowerShell.EditorServices.Protocol.Server.LanguageServer..ctor()
   at Microsoft.PowerShell.EditorServices.Host.Program.Main(String[] args)

We shouldn't be calling this method because there's a version guard around it checking for versions higher than v3. I think that the CLR may still be looking for the method despite it not being called in the code path. I'm going to try to debug the issue and see if I can work around it. If not, we may have to hold off on advertising PowerShell v3 and v4 support until we can resolve the problem.

@daviwil
Copy link
Contributor Author

daviwil commented Feb 8, 2016

Yeah, execution doesn't even make it into the Initialize method. I'm setting break points in there that never get hit. Looks like we're going to have to use per-version implementation classes :/

I think we should be able to fix this without introducing separate assemblies though. We just need to make sure a missing method isn't used explicitly in a code path that should support multiple versions. Hiding these calls behind an interface should help. I might try this briefly to see if it works.

@daviwil
Copy link
Contributor Author

daviwil commented Feb 8, 2016

OK, I'm going to make the call to push this to 0.5.0. Last minute changes like this are a little risky so I'd rather just have people wait until the next release for multi-version support. I'll try to get a PS v3 build machine going on AppVeyor so we can verify the support matrix a little more easily in the future.

@daviwil daviwil modified the milestones: 0.5.0, 0.4.0 Feb 8, 2016
@adamdriscoll
Copy link
Contributor

Bummer!

@daviwil
Copy link
Contributor Author

daviwil commented Mar 8, 2016

Working on this again. Some tasks left to complete:

  • Disable use of ScriptAnalyzer for v3 and v4
  • Don't call SetDebuggerStepMode to pause debugger. Need to use reflection to invoke this method to avoid MissingMethodException even though

@KirkMunro
Copy link

PSScriptAnalyzer works for v3 and v4. Why are you disabling that module for those versions?

@daviwil
Copy link
Contributor Author

daviwil commented Mar 8, 2016

For now, it's because there's a wholly separate PSScriptAnalyzer binary for v3/v4 support. I'm not sure if it's possible to dynamically switch out which binary I'm using at runtime for this.

@daviwil
Copy link
Contributor Author

daviwil commented Mar 8, 2016

I am definitely open to suggestions on how to deal with that, though. I didn't see it as a high priority since the way I integrate Script Analyzer is going to change in the next big version.

@adamdriscoll
Copy link
Contributor

You couldn't pause in previous versions.

@KirkMunro
Copy link

@daviwil: You shouldn't have to worry about their being a separate binary for v3/v4 support though. Just import the parent module (PSScriptAnalyzer) and it will load the appropriate nested binary module depending on your version of PowerShell.

@daviwil
Copy link
Contributor Author

daviwil commented Mar 8, 2016

@adamdriscoll: Yeah, I'm also pretty sure that's the case. What do you do in PoshTools when the user clicks pause, is it just a no-op or do you show some kind of warning?

@KirkMunro: That's the problem, I'm not using Script Analyzer as a module right now, I'm compiling directly against binaries that I bundle with the VS Code extension. The ultimate goal is to use whatever PSScriptAnalyzer that the user has installed on their machine by letting Script Analyzer register itself as an analysis provider for Editor Services. That won't come until I get the new editor extension model started.

@KirkMunro
Copy link

@daviwil Gotcha, that makes sense.

@adamdriscoll
Copy link
Contributor

@daviwil That's a good question. I'll have to check. I'm gonna guess no-op though.

daviwil added a commit that referenced this issue Mar 9, 2016
This change finishes our PowerShell v3 and v4 support by conditionally
changing behavior for those versions.  This works by using an interface
facade in front of any version-specific behavior so that the CLR doesn't
try to resolve method names that aren't available in a particular version.

Resolves #73.
@daviwil daviwil closed this as completed in c3c19b1 Mar 9, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Enhancement A feature request (enhancement).
Projects
None yet
Development

No branches or pull requests

3 participants