Skip to content

Commit 08bdc0f

Browse files
author
Kapil Borle
committed
Fix merge conflict with 'master'
2 parents ad50303 + b8b8b0b commit 08bdc0f

File tree

10 files changed

+398
-62
lines changed

10 files changed

+398
-62
lines changed

.vscodeignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ build/**
77
bin/EditorServices.log
88
bin/DebugAdapter.log
99
bin/*.vshost.*
10+
bin/PowerShell/**
1011
logs/**
1112
sessions/**

examples/PSScriptAnalyzerSettings.psd1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
'PSReservedParams',
1717
'PSShouldProcess',
1818
'PSUseApprovedVerbs',
19+
'PSAvoidUsingAliases',
1920
'PSUseDeclaredVarsMoreThanAssigments')
2021

2122
# Do not analyze the following rules. Use ExcludeRules when you have

package.json

Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@
2727
"main": "./out/main",
2828
"activationEvents": [
2929
"onLanguage:powershell",
30-
"onCommand:PowerShell.NewProjectFromTemplate"
30+
"onCommand:PowerShell.NewProjectFromTemplate",
31+
"onCommand:PowerShell.OpenExamplesFolder",
32+
"onCommand:PowerShell.StartDebugSession"
3133
],
3234
"dependencies": {
3335
"vscode-languageclient": "1.3.1"
@@ -139,6 +141,11 @@
139141
"command": "PowerShell.NewProjectFromTemplate",
140142
"title": "Create New Project from Plaster Template",
141143
"category": "PowerShell"
144+
},
145+
{
146+
"command": "PowerShell.OpenExamplesFolder",
147+
"title": "Open Examples Folder",
148+
"category": "PowerShell"
142149
}
143150
],
144151
"snippets": [
@@ -157,10 +164,11 @@
157164
},
158165
"program": "./out/debugAdapter.js",
159166
"runtime": "node",
160-
167+
"languages": ["powershell"],
168+
"startSessionCommand": "PowerShell.StartDebugSession",
161169
"configurationSnippets": [
162170
{
163-
"label": "PowerShell: Launch Current File Configuration",
171+
"label": "PowerShell: Launch Current Script Configuration",
164172
"description": "A new configuration for launching the current opened PowerShell script",
165173
"body": {
166174
"type": "PowerShell",
@@ -172,7 +180,7 @@
172180
}
173181
},
174182
{
175-
"label": "PowerShell: Launch Configuration",
183+
"label": "PowerShell: Launch Script Configuration",
176184
"description": "A new configuration for launching a PowerShell script",
177185
"body": {
178186
"type": "PowerShell",
@@ -182,22 +190,39 @@
182190
"args": [],
183191
"cwd": "^\"\\${workspaceRoot}\""
184192
}
193+
},
194+
{
195+
"label": "PowerShell: Attach to PowerShell Process Configuration",
196+
"description": "A new configuration for debugging a runspace in another process.",
197+
"body": {
198+
"type": "PowerShell",
199+
"request": "attach",
200+
"name": "PowerShell Attach to Process",
201+
"processId": "${ProcessId}",
202+
"runspaceId": "1"
203+
}
204+
},
205+
{
206+
"label": "PowerShell: Launch Interactive Session Configuration",
207+
"description": "A new configuration for debugging an interactive session.",
208+
"body": {
209+
"type": "PowerShell",
210+
"request": "launch",
211+
"name": "PowerShell Interactive Session"
212+
}
185213
}
186214
],
187215

188216
"configurationAttributes": {
189217
"launch": {
190-
"required": [
191-
"script"
192-
],
193218
"properties": {
194219
"program": {
195220
"type": "string",
196221
"description": "Deprecated. Please use the 'script' property instead to specify the absolute path to the PowerShell script to launch under the debugger."
197222
},
198223
"script": {
199224
"type": "string",
200-
"description": "Absolute path to the PowerShell script to launch under the debugger."
225+
"description": "Optional: Absolute path to the PowerShell script to launch under the debugger."
201226
},
202227
"args": {
203228
"type": "array",
@@ -213,6 +238,23 @@
213238
"default": "${workspaceRoot}"
214239
}
215240
}
241+
},
242+
"attach": {
243+
"properties": {
244+
"computerName": {
245+
"type": "string",
246+
"description": "Optional: The computer name to which a remote session will be established. Works only on PowerShell 4 and above."
247+
},
248+
"processId": {
249+
"type": "number",
250+
"description": "The ID of the process to be attached. Works only on PowerShell 5 and above."
251+
},
252+
"runspaceId": {
253+
"type": "number",
254+
"description": "Optional: The ID of the runspace to debug in the attached process. Defaults to 1. Works only on PowerShell 5 and above.",
255+
"default": 1
256+
}
257+
}
216258
}
217259
},
218260
"initialConfigurations": [
@@ -223,6 +265,18 @@
223265
"script": "${file}",
224266
"args": [],
225267
"cwd": "${file}"
268+
},
269+
{
270+
"type": "PowerShell",
271+
"request": "attach",
272+
"name": "PowerShell Attach",
273+
"processId": "12345"
274+
},
275+
{
276+
"type": "PowerShell",
277+
"request": "launch",
278+
"name": "PowerShell Interactive Session",
279+
"cwd": "${workspaceRoot}"
226280
}
227281
]
228282
}

snippets/PowerShell.json

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,65 @@
11
{
2+
"ModuleManifest": {
3+
"prefix": "manifest",
4+
"body": [
5+
"@{",
6+
"\t# If authoring a script module, the RootModule is your .psm1 file",
7+
"\tRootModule = '${module:MyModule}.psm1'",
8+
"",
9+
"\tAuthor = '${author:Cool Person <[email protected]>}",
10+
"",
11+
"\tCompanyName = '${company:Contoso Inc.}'",
12+
"",
13+
"\tModuleVersion = '${ModuleVersion:0.1}'",
14+
"",
15+
"\tGUID = '<pasteNewGUIDhere>'",
16+
"",
17+
"\tCopyright = '2017 ${company:Copyright Holder}",
18+
"",
19+
"\tDescription = '${Description:What does this module do?}'",
20+
"",
21+
"\t# Minimum PowerShell version supported by this module (optional, recommended)",
22+
"\t# PowerShellVersion = ''",
23+
"",
24+
"\t# Which PowerShell Editions does this module work with? (Core, Desktop)",
25+
"\tCompatiblePSEditions = @('Desktop', 'Core')",
26+
"",
27+
"\t# Which PowerShell functions are exported from your module? (eg. Get-CoolObject)",
28+
"\tFunctionsToExport = @('')",
29+
"",
30+
"\t# Which PowerShell aliases are exported from your module? (eg. gco)",
31+
"\tAliasesToExport = @('')",
32+
"",
33+
"\t# Which PowerShell variables are exported from your module? (eg. Fruits, Vegetables)",
34+
"\tVariablesToExport = @('')",
35+
"",
36+
"\t# PowerShell Gallery: Define your module's metadata",
37+
"\tPrivateData = @{",
38+
"\t\tPSData = @{",
39+
"\t\t\t# What keywords represent your PowerShell module? (eg. cloud, tools, framework, vendor)",
40+
"\t\t\tTags = @('${tag1:cooltag1}', '${tag2:cooltag2}')",
41+
"",
42+
"\t\t\t# What software license is your code being released under? (see https://opensource.org/licenses)",
43+
"\t\t\tLicenseUri = ''",
44+
"",
45+
"\t\t\t# What is the URL to your project's website?",
46+
"\t\t\tProjectUri = ''",
47+
"",
48+
"\t\t\t# What is the URI to a custom icon file for your project? (optional)",
49+
"\t\t\tIconUri = ''",
50+
"",
51+
"\t\t\t# What new features, bug fixes, or deprecated features, are part of this release?",
52+
"\t\t\tReleaseNotes = @'",
53+
"'@",
54+
"\t\t}",
55+
"\t}",
56+
"",
57+
"\t# If your module supports updateable help, what is the URI to the help archive? (optional)",
58+
"\t# HelpInfoURI = ''",
59+
"}"
60+
],
61+
"description": "Basic skeleton for a PowerShell module manifest, complete with PowerShell Gallery metadata."
62+
},
263
"Example-Class": {
364
"prefix": "ex-class",
465
"body": [
@@ -810,4 +871,4 @@
810871
],
811872
"description": "sequence snippet (for use inside a workflow)"
812873
}
813-
}
874+
}

src/debugAdapter.ts

Lines changed: 102 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -26,49 +26,107 @@ var debugAdapterLogWriter =
2626
// debug server
2727
process.stdin.pause();
2828

29-
// Read the details of the current session to learn
30-
// the connection details for the debug service
31-
let sessionDetails = utils.readSessionFile();
32-
33-
// Establish connection before setting up the session
34-
debugAdapterLogWriter.write("Connecting to port: " + sessionDetails.debugServicePort + "\r\n");
35-
let debugServiceSocket = net.connect(sessionDetails.debugServicePort, '127.0.0.1');
36-
37-
// Write any errors to the log file
38-
debugServiceSocket.on(
39-
'error',
40-
(e) => debugAdapterLogWriter.write("Socket connect ERROR: " + e + "\r\n"));
41-
42-
// Route any output from the socket through stdout
43-
debugServiceSocket.on(
44-
'data',
45-
(data: Buffer) => process.stdout.write(data));
46-
47-
// Wait for the connection to complete
48-
debugServiceSocket.on(
49-
'connect',
50-
() => {
51-
debugAdapterLogWriter.write("Connected to socket!\r\n\r\n");
52-
53-
// When data comes on stdin, route it through the socket
54-
process.stdin.on(
55-
'data',
56-
(data: Buffer) => debugServiceSocket.write(data));
57-
58-
// Resume the stdin stream
59-
process.stdin.resume();
60-
});
61-
62-
// When the socket closes, end the session
63-
debugServiceSocket.on(
64-
'close',
65-
() => {
66-
debugAdapterLogWriter.write("Socket closed, shutting down.");
67-
68-
// Close after a short delay to give the client time
69-
// to finish up
70-
setTimeout(() => {
29+
function startDebugging() {
30+
// Read the details of the current session to learn
31+
// the connection details for the debug service
32+
let sessionDetails = utils.readSessionFile();
33+
34+
// Establish connection before setting up the session
35+
debugAdapterLogWriter.write("Connecting to port: " + sessionDetails.debugServicePort + "\r\n");
36+
37+
let isConnected = false;
38+
let debugServiceSocket = net.connect(sessionDetails.debugServicePort, '127.0.0.1');
39+
40+
// Write any errors to the log file
41+
debugServiceSocket.on(
42+
'error',
43+
(e) => {
44+
debugAdapterLogWriter.write("Socket ERROR: " + e + "\r\n")
45+
debugAdapterLogWriter.close();
46+
debugServiceSocket.destroy();
7147
process.exit(0);
72-
}, 1000);
48+
});
49+
50+
// Route any output from the socket through stdout
51+
debugServiceSocket.on(
52+
'data',
53+
(data: Buffer) => process.stdout.write(data));
54+
55+
// Wait for the connection to complete
56+
debugServiceSocket.on(
57+
'connect',
58+
() => {
59+
isConnected = true;
60+
debugAdapterLogWriter.write("Connected to socket!\r\n\r\n");
61+
62+
// When data comes on stdin, route it through the socket
63+
process.stdin.on(
64+
'data',
65+
(data: Buffer) => debugServiceSocket.write(data));
66+
67+
// Resume the stdin stream
68+
process.stdin.resume();
69+
});
70+
71+
// When the socket closes, end the session
72+
debugServiceSocket.on(
73+
'close',
74+
() => {
75+
debugAdapterLogWriter.write("Socket closed, shutting down.");
76+
debugAdapterLogWriter.close();
77+
isConnected = false;
78+
79+
// Close after a short delay to give the client time
80+
// to finish up
81+
setTimeout(() => {
82+
process.exit(0);
83+
}, 2000);
84+
}
85+
)
86+
87+
process.on(
88+
'exit',
89+
(e) => {
90+
if (debugAdapterLogWriter) {
91+
debugAdapterLogWriter.write("Debug adapter process is exiting...");
92+
}
93+
}
94+
)
95+
}
96+
97+
var sessionFilePath = utils.getSessionFilePath();
98+
function waitForSessionFile(triesRemaining: number) {
99+
100+
debugAdapterLogWriter.write(`Waiting for session file, tries remaining: ${triesRemaining}...\r\n`);
101+
102+
if (triesRemaining > 0) {
103+
if (utils.checkIfFileExists(sessionFilePath)) {
104+
debugAdapterLogWriter.write(`Session file present, connecting to debug adapter...\r\n\r\n`);
105+
startDebugging();
106+
}
107+
else {
108+
// Wait for a second and try again
109+
setTimeout(
110+
() => waitForSessionFile(triesRemaining - 1),
111+
1000);
112+
}
113+
}
114+
else {
115+
debugAdapterLogWriter.write(`Timed out waiting for session file!\r\n`);
116+
var errorJson =
117+
JSON.stringify({
118+
type: "response",
119+
request_seq: 1,
120+
command: "initialize",
121+
success: false,
122+
message: "Timed out waiting for the PowerShell extension to start."
123+
});
124+
125+
process.stdout.write(
126+
`Content-Length: ${Buffer.byteLength(errorJson, 'utf8')}\r\n\r\n${errorJson}`,
127+
'utf8');
73128
}
74-
)
129+
}
130+
131+
// Wait for the session file to appear
132+
waitForSessionFile(30);

0 commit comments

Comments
 (0)