Change:
After updating the module to support getting memory, cpu, and command line for each process on windows (), the module can be used in more places within VSCode [x] Update existing version of the module that's being used in the terminal [x] Use the module in place of the PowerShell script in

Discussion:
'!src/vs/base/common/marked/marked.js', '!src/vs/base/common/winjs.base.js', '!src/vs/base/node/terminateProcess.sh', <del> '!src/vs/base/node/ps-win.ps1', </del> '!test/assert.js', // except specific folders

'out-build/paths.js', 'out-build/vs/**/*.{svg,png,cur,html}', 'out-build/vs/base/common/performance.js', <del> 'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh,ps-win.ps1}', </del> <ins> 'out-build/vs/base/node/{stdForkStart.js,terminateProcess.sh}', </ins> 'out-build/vs/base/browser/ui/octiconLabel/octicons/**', 'out-build/vs/workbench/browser/media/*-theme.css', 'out-build/vs/workbench/electron-browser/bootstrap/**',

"optionalDependencies": { "windows-foreground-love": "0.1.0", "windows-mutex": "^0.2.0", <del> "windows-process-tree": "0.2.0" </del> <ins> "windows-process-tree": "0.2.1" </ins> } }

<del> ################################################################################################ #  Copyright (c) Microsoft Corporation. All rights reserved. #  Licensed under the MIT License. See License.txt in the project root for license information. ################################################################################################ Param( [string]$ProcessName = "code.exe", [int]$MaxSamples = 10 ) $processLength = "process(".Length function Get-MachineInfo { $model = (Get-WmiObject -Class Win32_Processor).Name $memory = (Get-WmiObject -Class Win32_PhysicalMemory | Measure-Object -Property Capacity -Sum).Sum / 1MB $wmi_cs = Get-WmiObject -Class Win32_ComputerSystem return @{ "type" = "machineInfo" "model" = $model "processors" = $wmi_cs.NumberOfProcessors "logicalProcessors" = $wmi_cs.NumberOfLogicalProcessors "totalMemory" = $memory } } $machineInfo = Get-MachineInfo function Get-MachineState { $proc = Get-WmiObject Win32_Processor $os = Get-WmiObject win32_OperatingSystem return @{ "type" = 'machineState' "cpuLoad" = $proc.LoadPercentage "handles" = (Get-Process | Measure-Object Handles -Sum).Sum "memory" = @{ "total" = $os.TotalVisibleMemorySize "free" = $os.FreePhysicalMemory "swapTotal" = $os.TotalVirtualMemorySize "swapFree" = $os.FreeVirtualMemory } } } $machineState = Get-MachineState $processId2CpuLoad = @{} function Get-PerformanceCounters ($logicalProcessors) { $counterError # In a first round we get the performance counters and the process ids. $counters =  (Get-Counter ("Process(*)% Processor Time", "Process(*)ID Process") -ErrorAction SilentlyContinue).CounterSamples $processKey2Id = @{} foreach ($counter in $counters) { if ($counter.Status -ne 0) { continue } $path = $counter.path; $segments = $path.Split(""); $kind = $segments[4]; $processKey = $segments[3].Substring($processLength, $segments[3].Length - $processLength - 1) if ($kind -eq "id process") { $processKey2Id[$processKey] = [uint32]$counter.CookedValue } } foreach ($counter in $counters) { if ($counter.Status -ne 0) { continue } $path = $counter.path; $segments = $path.Split(""); $kind = $segments[4]; $processKey = $segments[3].Substring($processLength, $segments[3].Length - $processLength - 1) if ($kind -eq "% processor time") { $array = New-Object double[] ($MaxSamples + 1) $array[0] = ($counter.CookedValue / $logicalProcessors) $processId = $processKey2Id[$processKey] if ($processId) { $processId2CpuLoad[$processId] = $array } } } # Now lets sample another 10 times but only the processor time $samples = Get-Counter "Process(*)% Processor Time" -SampleInterval 1 -MaxSamples $MaxSamples -ErrorAction SilentlyContinue for ($s = 0; $s -lt $samples.Count; $s++) { $counters = $samples[$s].CounterSamples; foreach ($counter in $counters) { if ($counter.Status -ne 0) { continue } $path = $counter.path; $segments = $path.Split(""); $processKey = $segments[3].Substring($processLength, $segments[3].Length - $processLength - 1) $processKey = $processKey2Id[$processKey]; if ($processKey) { $processId2CpuLoad[$processKey][$s + 1] = ($counter.CookedValue / $logicalProcessors) } } } } Get-PerformanceCounters -logicalProcessors $machineInfo.logicalProcessors $topElements = New-Object PSObject[] $processId2CpuLoad.Keys.Count; $index = 0; foreach ($key in $processId2CpuLoad.Keys) { $obj = [PSCustomObject]@{ ProcessId = $key Load = ($processId2CpuLoad[$key] | Measure-Object -Sum).Sum / ($MaxSamples + 1) } $topElements[$index] = $obj $index++ } $topElements = $topElements | Sort-Object Load -Descending # Get all code processes $codeProcesses = @{} foreach ($item in Get-WmiObject Win32_Process -Filter "name = '$ProcessName'") { $codeProcesses[$item.ProcessId] = $item } foreach ($item in Get-WmiObject Win32_Process -Filter "name = 'codeHelper.exe'") { $codeProcesses[$item.ProcessId] = $item } $otherProcesses = @{} foreach ($item in Get-WmiObject Win32_Process -Filter "name Like '%'") { if (!($codeProcesses.Contains($item.ProcessId))) { $otherProcesses[$item.ProcessId] = $item } } $modified = $false do { $toDelete = @() $modified = $false foreach ($item in $otherProcesses.Values) { if ($codeProcesses.Contains([uint32]$item.ParentProcessId)) { $codeProcesses[$item.ProcessId] = $item; $toDelete += $item } } foreach ($item in $toDelete) { $otherProcesses.Remove([uint32]$item.ProcessId) $modified = $true } } while ($modified) $result = New-Object PSObject[] (2 + [math]::Min(5, $topElements.Count) + $codeProcesses.Count) $result[0] = $machineInfo $result[1] = $machineState $index = 2; for($i = 0; $i -lt 5 -and $i -lt $topElements.Count; $i++) { $element = $topElements[$i] $item = $codeProcesses[[uint32]$element.ProcessId] if (!$item) { $item = $otherProcesses[[uint32]$element.ProcessId] } if ($item) { $cpuLoad = $processId2CpuLoad[[uint32]$item.ProcessId] | % { [pscustomobject] $_ } $result[$index] = [pscustomobject]@{ "type" = "topProcess" "name"            = $item.Name "processId"       = $item.ProcessId "parentProcessId" = $item.ParentProcessId "commandLine"     = $item.CommandLine "handles"         = $item.HandleCount "cpuLoad"         = $cpuLoad "workingSetSize"  = $item.WorkingSetSize } $index++ } } foreach ($item in $codeProcesses.Values) { # we need to convert this otherwise to JSON with create a value, count object and not an inline array $cpuLoad = $processId2CpuLoad[[uint32]$item.ProcessId] | % { [pscustomobject] $_ } $result[$index] = [pscustomobject]@{ "type"            = "processInfo" "name"            = $item.Name "processId"       = $item.ProcessId "parentProcessId" = $item.ParentProcessId "commandLine"     = $item.CommandLine "handles"         = $item.HandleCount "cpuLoad"         = $cpuLoad "workingSetSize"  = $item.WorkingSetSize } $index++ } $result | ConvertTo-Json -Depth 99 </del>

'use strict'; <del> import { spawn, exec } from 'child_process'; import * as path from 'path'; import * as nls from 'vs/nls'; import URI from 'vs/base/common/uri'; </del> <ins> import { exec } from 'child_process'; </ins> export interface ProcessItem { name: string;

if (process.platform === 'win32') { <del> console.log(nls.localize('collecting', 'Collecting CPU and memory information. This might take a couple of seconds.')); interface ProcessInfo { type: 'processInfo'; name: string; processId: number; parentProcessId: number; commandLine: string; handles: number; cpuLoad: number[]; workingSetSize: number; } interface TopProcess { type: 'topProcess'; name: string; processId: number; parentProcessId: number; commandLine: string; handles: number; cpuLoad: number[]; workingSetSize: number; } type Item = ProcessInfo | TopProcess; </del> const cleanUNCPrefix = (value: string): string => { if (value.indexOf('?') === 0) { return value.substr(4);

} }; <del> const execMain = path.basename(process.execPath); const script = URI.parse(require.toUrl('vs/base/node/ps-win.ps1')).fsPath; const commandLine = `& {& '${script}' -ProcessName '${execMain}' -MaxSamples 3}`; const cmd = spawn('powershell.exe', ['-NoProfile', '-ExecutionPolicy', 'Bypass', '-Command', commandLine]); let stdout = ''; let stderr = ''; cmd.stdout.on('data', data => { stdout += data.toString(); }); </del> <ins> (import('windows-process-tree')).then(windowsProcessTree => { windowsProcessTree.getProcessList(rootPid, (processList) => { windowsProcessTree.getProcessCpuUsage(processList, (completeProcessList) => { const processItems: Map<number, ProcessItem> = new Map(); completeProcessList.forEach(process => { const commandLine = cleanUNCPrefix(process.commandLine); processItems.set(process.pid, { name: findName(commandLine), cmd: commandLine, pid: process.pid, ppid: process.ppid, load: process.cpu, mem: process.memory }); }); </ins> <del> cmd.stderr.on('data', data => { stderr += data.toString(); }); </del> <ins> rootItem = processItems.get(rootPid); if (rootItem) { processItems.forEach(item => { let parent = processItems.get(item.ppid); if (parent) { if (!parent.children) { parent.children = []; } parent.children.push(item); } }); </ins> <del> cmd.on('exit', () => { if (stderr.length > 0) { reject(new Error(stderr)); return; } let processItems: Map<number, ProcessItem> = new Map(); try { const items: Item[] = JSON.parse(stdout); for (const item of items) { if (item.type === 'processInfo') { let load = 0; if (item.cpuLoad) { for (let value of item.cpuLoad) { load += value; </del> <ins> processItems.forEach(item => { if (item.children) { item.children = item.children.sort((a, b) => a.pid - b.pid); </ins> } <del> load = load / item.cpuLoad.length; } else { load = -1; } let commandLine = cleanUNCPrefix(item.commandLine); processItems.set(item.processId, { name: findName(commandLine), cmd: commandLine, pid: item.processId, ppid: item.parentProcessId, load: load, mem: item.workingSetSize </del> }); <ins> resolve(rootItem); } else { reject(new Error(`Root process ${rootPid} not found`)); </ins> } <del> } rootItem = processItems.get(rootPid); if (rootItem) { processItems.forEach(item => { let parent = processItems.get(item.ppid); if (parent) { if (!parent.children) { parent.children = []; } parent.children.push(item); } }); processItems.forEach(item => { if (item.children) { item.children = item.children.sort((a, b) => a.pid - b.pid); } }); resolve(rootItem); } else { reject(new Error(`Root process ${rootPid} not found`)); } } catch (error) { console.log(stdout); reject(error); } </del> <ins> }); }, windowsProcessTree.ProcessDataFlag.CommandLine | windowsProcessTree.ProcessDataFlag.Memory); </ins> }); } else {	// OS X & Linux

bindings "^1.2.1" nan "^2.1.0" <del> windows-process-tree@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/windows-process-tree/-/windows-process-tree-0.2.0.tgz#04dc0507df292a7984daf0d35861bd1ebaff7ae8" </del> <ins> windows-process-tree@0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/windows-process-tree/-/windows-process-tree-0.2.1.tgz#d750f8592bd956e89f8dc565bc47be6430d3df6e" </ins> dependencies: nan "^2.6.2"