Skip to content

Commit 81e33a5

Browse files
committed
Convert Editor Services host to PowerShell module
This (unfortunately large) commit includes two important design changes to the PowerShell Editor Services hosting model. The first change is the conversion of the host process to be loaded as a PowerShell module inside of powershell.exe. This change enables a lot of interesting possibilities including the ability to run the Editor Services host on a remote machine and connect to it from a client machine. Another benefit of this approach is the ability to load assembly dependencies based on the version of PowerShell in which the host is loaded. Following on from the previous point, the second change is to introduce a separate build of the PSES host which is compiled against the Nano Server SDK. This enables the PSES host to be loaded in the edition of PowerShell that is shipped with Nano Server. Both of these changes bring us much closer to enabling a remote editing experience which would allow someone to use VS Code on a Linux or OSX machine and connect to an Editor Services host running in a Windows or Nano Server VM. We will need to finish the WebSockets channel support before this is fully possible, though.
1 parent 1c73771 commit 81e33a5

File tree

63 files changed

+1558
-484
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

63 files changed

+1558
-484
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
_ReSharper*
22
[Bb]in
3+
bin-nano
34
obj
45
objd
56
out/

PowerShellEditorServices.sln

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 14
4-
VisualStudioVersion = 14.0.24720.0
4+
VisualStudioVersion = 14.0.25123.0
55
MinimumVisualStudioVersion = 10.0.40219.1
66
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{F594E7FD-1E72-4E51-A496-B019C2BA3180}"
77
EndProject
@@ -43,6 +43,12 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerShellEditorServices.Ch
4343
EndProject
4444
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PowerShellEditorServices.Test.Channel.WebSocket", "test\PowerShellEditorServices.Test.Channel.WebSocket\PowerShellEditorServices.Test.Channel.WebSocket.csproj", "{9D98120C-9601-4678-AD50-EF2808DABAC9}"
4545
EndProject
46+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "desktop", "desktop", "{EE0A010C-E246-49AE-92E7-AD4320C45086}"
47+
EndProject
48+
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "nano", "nano", "{5B98CD12-46AA-47CB-95B9-AFF11EA76489}"
49+
EndProject
50+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Nano.PowerShellEditorServices", "src\PowerShellEditorServices\Nano.PowerShellEditorServices.csproj", "{02DC1749-7657-4A41-9865-313F07DE8901}"
51+
EndProject
4652
Global
4753
GlobalSection(SolutionConfigurationPlatforms) = preSolution
4854
Debug|Any CPU = Debug|Any CPU
@@ -93,21 +99,28 @@ Global
9399
{9D98120C-9601-4678-AD50-EF2808DABAC9}.Debug|Any CPU.Build.0 = Debug|Any CPU
94100
{9D98120C-9601-4678-AD50-EF2808DABAC9}.Release|Any CPU.ActiveCfg = Release|Any CPU
95101
{9D98120C-9601-4678-AD50-EF2808DABAC9}.Release|Any CPU.Build.0 = Release|Any CPU
102+
{02DC1749-7657-4A41-9865-313F07DE8901}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
103+
{02DC1749-7657-4A41-9865-313F07DE8901}.Debug|Any CPU.Build.0 = Debug|Any CPU
104+
{02DC1749-7657-4A41-9865-313F07DE8901}.Release|Any CPU.ActiveCfg = Release|Any CPU
105+
{02DC1749-7657-4A41-9865-313F07DE8901}.Release|Any CPU.Build.0 = Release|Any CPU
96106
EndGlobalSection
97107
GlobalSection(SolutionProperties) = preSolution
98108
HideSolutionNode = FALSE
99109
EndGlobalSection
100110
GlobalSection(NestedProjects) = preSolution
101111
{F4BDE3D0-3EEF-4157-8A3E-722DF7ADEF60} = {AF08DA0C-B0A6-47AD-AC55-E13C687D4A91}
102112
{C33B6B9D-E61C-45A3-9103-895FD82A5C1E} = {AF08DA0C-B0A6-47AD-AC55-E13C687D4A91}
103-
{81E8CBCD-6319-49E7-9662-0475BD0791F4} = {F594E7FD-1E72-4E51-A496-B019C2BA3180}
104-
{B2F6369A-D737-4AFD-8B81-9B094DB07DA7} = {F594E7FD-1E72-4E51-A496-B019C2BA3180}
113+
{81E8CBCD-6319-49E7-9662-0475BD0791F4} = {EE0A010C-E246-49AE-92E7-AD4320C45086}
114+
{B2F6369A-D737-4AFD-8B81-9B094DB07DA7} = {EE0A010C-E246-49AE-92E7-AD4320C45086}
105115
{3A5DDD20-5BD0-42F4-89F4-ACC0CE554028} = {422E561A-8118-4BE7-A54F-9309E4F03AAE}
106116
{8ED116F4-9DDF-4C49-AB96-AE462E3D64C3} = {422E561A-8118-4BE7-A54F-9309E4F03AAE}
107117
{6A20B9E9-DE66-456E-B4F5-ACFD1A95C3CA} = {422E561A-8118-4BE7-A54F-9309E4F03AAE}
108-
{F8A0946A-5D25-4651-8079-B8D5776916FB} = {F594E7FD-1E72-4E51-A496-B019C2BA3180}
118+
{F8A0946A-5D25-4651-8079-B8D5776916FB} = {EE0A010C-E246-49AE-92E7-AD4320C45086}
109119
{E3A5CF5D-6E41-44AC-AE0A-4C227E4BACD4} = {422E561A-8118-4BE7-A54F-9309E4F03AAE}
110-
{A6663F64-3C3D-461F-8A05-0CC4CA7A9945} = {F594E7FD-1E72-4E51-A496-B019C2BA3180}
120+
{A6663F64-3C3D-461F-8A05-0CC4CA7A9945} = {EE0A010C-E246-49AE-92E7-AD4320C45086}
111121
{9D98120C-9601-4678-AD50-EF2808DABAC9} = {422E561A-8118-4BE7-A54F-9309E4F03AAE}
122+
{EE0A010C-E246-49AE-92E7-AD4320C45086} = {F594E7FD-1E72-4E51-A496-B019C2BA3180}
123+
{5B98CD12-46AA-47CB-95B9-AFF11EA76489} = {F594E7FD-1E72-4E51-A496-B019C2BA3180}
124+
{02DC1749-7657-4A41-9865-313F07DE8901} = {5B98CD12-46AA-47CB-95B9-AFF11EA76489}
112125
EndGlobalSection
113126
EndGlobal
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#
2+
# Module manifest for module 'PowerShellEditorServices'
3+
#
4+
# Generated by: daviwil
5+
#
6+
# Generated on: 5/12/2016
7+
#
8+
9+
@{
10+
11+
# Script module or binary module file associated with this manifest.
12+
RootModule = 'PowerShellEditorServices.psm1'
13+
14+
# Version number of this module.
15+
ModuleVersion = '0.7.0'
16+
17+
# Supported PSEditions
18+
#CompatiblePSEditions = @("Desktop", "Core")
19+
20+
# ID used to uniquely identify this module
21+
GUID = '9ca15887-53a2-479a-9cda-48d26bcb6c47'
22+
23+
# Author of this module
24+
Author = 'Microsoft'
25+
26+
# Company or vendor of this module
27+
CompanyName = 'Microsoft'
28+
29+
# Copyright statement for this module
30+
Copyright = '(c) 2016 Microsoft. All rights reserved.'
31+
32+
# Description of the functionality provided by this module
33+
# Description = ''
34+
35+
# Minimum version of the Windows PowerShell engine required by this module
36+
# PowerShellVersion = ''
37+
38+
# Name of the Windows PowerShell host required by this module
39+
#PowerShellHostName = ''
40+
41+
# Minimum version of the Windows PowerShell host required by this module
42+
# PowerShellHostVersion = ''
43+
44+
# Minimum version of Microsoft .NET Framework required by this module
45+
# DotNetFrameworkVersion = ''
46+
47+
# Minimum version of the common language runtime (CLR) required by this module
48+
# CLRVersion = ''
49+
50+
# Processor architecture (None, X86, Amd64) required by this module
51+
# ProcessorArchitecture = ''
52+
53+
# Modules that must be imported into the global environment prior to importing this module
54+
# RequiredModules = @()
55+
56+
# Assemblies that must be loaded prior to importing this module
57+
# RequiredAssemblies = @()
58+
59+
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
60+
# ScriptsToProcess = @()
61+
62+
# Type files (.ps1xml) to be loaded when importing this module
63+
# TypesToProcess = @()
64+
65+
# Format files (.ps1xml) to be loaded when importing this module
66+
# FormatsToProcess = @()
67+
68+
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
69+
# NestedModules = @()
70+
71+
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
72+
FunctionsToExport = @('Start-EditorServicesHost')
73+
74+
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
75+
CmdletsToExport = @()
76+
77+
# Variables to export from this module
78+
VariablesToExport = '*'
79+
80+
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
81+
AliasesToExport = @()
82+
83+
# DSC resources to export from this module
84+
# DscResourcesToExport = @()
85+
86+
# List of all modules packaged with this module
87+
# ModuleList = @()
88+
89+
# List of all files packaged with this module
90+
# FileList = @()
91+
92+
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
93+
PrivateData = @{
94+
95+
PSData = @{
96+
97+
# Tags applied to this module. These help with module discovery in online galleries.
98+
# Tags = @()
99+
100+
# A URL to the license for this module.
101+
# LicenseUri = ''
102+
103+
# A URL to the main website for this project.
104+
# ProjectUri = ''
105+
106+
# A URL to an icon representing this module.
107+
# IconUri = ''
108+
109+
# ReleaseNotes of this module
110+
# ReleaseNotes = ''
111+
112+
} # End of PSData hashtable
113+
114+
} # End of PrivateData hashtable
115+
116+
# HelpInfo URI of this module
117+
# HelpInfoURI = ''
118+
119+
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
120+
# DefaultCommandPrefix = ''
121+
122+
}
123+
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
if (!$PSVersionTable.PSEdition -or $PSVersionTable.PSEdition -eq "Desktop") {
2+
Add-Type -Path "$PSScriptRoot\bin\Desktop\Microsoft.PowerShell.EditorServices.dll"
3+
Add-Type -Path "$PSScriptRoot\bin\Desktop\Microsoft.PowerShell.EditorServices.Host.dll"
4+
}
5+
else {
6+
Add-Type -Path "$PSScriptRoot\bin\Nano\Microsoft.PowerShell.EditorServices.Nano.dll"
7+
}
8+
9+
function Start-EditorServicesHost {
10+
[CmdletBinding()]
11+
param(
12+
[Parameter(Mandatory=$true)]
13+
[ValidateNotNullOrEmpty()]
14+
[string]
15+
$HostName,
16+
17+
[Parameter(Mandatory=$true)]
18+
[ValidateNotNullOrEmpty()]
19+
[string]
20+
$HostProfileId,
21+
22+
[Parameter(Mandatory=$true)]
23+
[ValidateNotNullOrEmpty()]
24+
[string]
25+
$HostVersion,
26+
27+
[Parameter(Mandatory=$true)]
28+
[ValidateNotNullOrEmpty()]
29+
[string]
30+
$LanguageServicePipeName,
31+
32+
[Parameter(Mandatory=$true)]
33+
[ValidateNotNullOrEmpty()]
34+
[string]
35+
$DebugServicePipeName,
36+
37+
[ValidateNotNullOrEmpty()]
38+
[string]
39+
$BundledModulesPath,
40+
41+
[Parameter(Mandatory=$true)]
42+
[ValidateNotNullOrEmpty()]
43+
$LogPath,
44+
45+
[ValidateSet("Normal", "Verbose", "Error")]
46+
$LogLevel = "Normal",
47+
48+
[switch]
49+
$WaitForCompletion,
50+
51+
[switch]
52+
$WaitForDebugger
53+
)
54+
55+
$editorServicesHost = $null
56+
$hostDetails = [Microsoft.PowerShell.EditorServices.Session.HostDetails]::new($HostName, $HostProfileId, [System.Version]::new($HostVersion))
57+
58+
try {
59+
$editorServicesHost =
60+
[Microsoft.PowerShell.EditorServices.Host.EditorServicesHost]::new(
61+
$hostDetails,
62+
$BundledModulesPath,
63+
$WaitForDebugger.IsPresent);
64+
65+
# Build the profile paths using the root paths of the current $profile variable
66+
$profilePaths = [Microsoft.PowerShell.EditorServices.Session.ProfilePaths]::new(
67+
$hostDetails.ProfileId,
68+
[System.IO.Path]::GetDirectoryName($profile.AllUsersAllHosts),
69+
[System.IO.Path]::GetDirectoryName($profile.CurrentUserAllHosts));
70+
71+
$editorServicesHost.StartLogging($LogPath, $LogLevel);
72+
$editorServicesHost.StartLanguageService($LanguageServicePipeName, $profilePaths);
73+
$editorServicesHost.StartDebugService($DebugServicePipeName, $profilePaths);
74+
75+
Write-Output "PowerShell Editor Services host has started."
76+
77+
if ($WaitForCompletion.IsPresent) {
78+
$editorServicesHost.WaitForCompletion();
79+
}
80+
}
81+
catch {
82+
Write-Error "PowerShell Editor Services host initialization failed, terminating."
83+
Write-Error $_.Exception
84+
}
85+
86+
return $editorServicesHost
87+
}

module/Start-EditorServices.ps1

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
param(
2+
[Parameter(Mandatory=$true)]
3+
[ValidateNotNullOrEmpty()]
4+
[string]
5+
$EditorServicesVersion,
6+
7+
[Parameter(Mandatory=$true)]
8+
[ValidateNotNullOrEmpty()]
9+
[string]
10+
$HostName,
11+
12+
[Parameter(Mandatory=$true)]
13+
[ValidateNotNullOrEmpty()]
14+
[string]
15+
$HostProfileId,
16+
17+
[Parameter(Mandatory=$true)]
18+
[ValidateNotNullOrEmpty()]
19+
[string]
20+
$HostVersion,
21+
22+
[Parameter(Mandatory=$true)]
23+
[ValidateNotNullOrEmpty()]
24+
[string]
25+
$LanguageServicePipeName,
26+
27+
[Parameter(Mandatory=$true)]
28+
[ValidateNotNullOrEmpty()]
29+
[string]
30+
$DebugServicePipeName,
31+
32+
[ValidateNotNullOrEmpty()]
33+
[string]
34+
$BundledModulesPath,
35+
36+
[ValidateNotNullOrEmpty()]
37+
$LogPath,
38+
39+
[ValidateSet("Normal", "Verbose", "Error")]
40+
$LogLevel,
41+
42+
[switch]
43+
$WaitForCompletion,
44+
45+
[switch]
46+
$WaitForDebugger
47+
)
48+
49+
# Add BundledModulesPath to $env:PSModulePath
50+
if ($BundledModulesPath) {
51+
$env:PSModulePath = $BundledModulesPath + ";" + $env:PSModulePath
52+
}
53+
54+
$parsedVersion = [System.Version]::new($EditorServicesVersion)
55+
Import-Module PowerShellEditorServices -RequiredVersion $parsedVersion -ErrorAction Stop
56+
57+
Start-EditorServicesHost `
58+
-HostName $HostName `
59+
-HostProfileId $HostProfileId `
60+
-HostVersion $HostVersion `
61+
-LogPath $LogPath `
62+
-LogLevel $LogLevel `
63+
-LanguageServicePipeName $LanguageServicePipeName `
64+
-DebugServicePipeName $DebugServicePipeName `
65+
-BundledModulesPath $BundledModulesPath `
66+
-WaitForCompletion:$WaitForCompletion.IsPresent `
67+
-WaitForDebugger:$WaitForDebugger.IsPresent

src/Microsoft.CoreSys.CSharp.Targets

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<!--
2+
***********************************************************************************************
3+
Microsoft.Windows.UI.Xaml.CSharp.targets
4+
5+
WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and have
6+
created a backup copy. Incorrect changes to this file will make it
7+
impossible to load or build your projects from the command-line or the IDE.
8+
9+
Copyright (C) Microsoft Corporation. All rights reserved.
10+
***********************************************************************************************
11+
-->
12+
13+
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
14+
<PropertyGroup>
15+
<TargetFrameworkIdentifier Condition="'$(TargetFrameworkIdentifier)' == ''">.NETCore</TargetFrameworkIdentifier>
16+
<TargetFrameworkVersion Condition="'$(TargetFrameworkVersion)' == ''">v4.5</TargetFrameworkVersion>
17+
<TargetPlatformVersion Condition="'$(TargetPlatformVersion)' == ''">8.0</TargetPlatformVersion>
18+
19+
<ImplicitlyExpandTargetPlatform Condition="'$(ImplicitlyExpandTargetPlatform)' == '' ">true</ImplicitlyExpandTargetPlatform>
20+
<ImplicitlyExpandTargetFramework Condition="'$(ImplicitlyExpandTargetFramework)' == '' ">true</ImplicitlyExpandTargetFramework>
21+
<NoStdLib Condition="'$(NoStdLib)' == ''">true</NoStdLib>
22+
<UseVSHostingProcess>false</UseVSHostingProcess>
23+
24+
25+
<!-- Supress the warnings in the 1st pass so that warnings are not repeated twice -->
26+
<SuppressWarningsInPass1 Condition="'$(SuppressWarningsInPass1)' == '' ">true</SuppressWarningsInPass1>
27+
28+
</PropertyGroup>
29+
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
30+
<Import Project="Microsoft.CoreSys.Common.targets" />
31+
</Project>

0 commit comments

Comments
 (0)