-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathhelper-webview2.ps1
More file actions
240 lines (212 loc) · 9.54 KB
/
helper-webview2.ps1
File metadata and controls
240 lines (212 loc) · 9.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
function Open-WebView2Docs {
<#
.SYNOPSIS
# WebView2-Docs.ps1 takes a WebView2 API name, and an optional parameter to say which language
# to use (WinRT, .NET, Win32), and opens the corresponding WebView2 API documentation page in
# the default browser.
.EXAMPLE
Launch-WebView2Docs AddHostObjectToScript -Language DotNet
.EXAMPLE
Launch-WebView2Docs -WhatIf AddHostObjectToScript
#>
param(
[Parameter(Mandatory=$true)]
[string] $Api,
[Parameter(Mandatory=$false)][ValidateSet("Unknown", "WinRT", "DotNet", "Win32")]
[string] $Language = "Unknown",
# Equivalent to specifying -Language WinRT
[switch] $WinRT,
# Equivalent to specifying -Language Win32
[switch] $Win32,
# Equivalent to specifying -Language DotNet
[switch] $DotNet,
# Pass this switch to not actually open the browser, but instead list all
# considered matches
[switch] $WhatIf,
# Consider all results in the WhatIf output not just filtered
[switch] $All
);
if ($Language -eq "Unknown") {
if ($WinRT) { $Language = "WinRT"; }
elseif ($DotNet) { $Language = "DotNet"; }
elseif ($Win32) { $Language = "Win32"; }
}
# We will query the MSDN search web API for its RSS result
# String templates in .NET use {0}, {1}, etc. as placeholders for values
$msdnSearchRssUriTemplate = "https://learn.microsoft.com/api/search/rss?search={0}&locale=en-us&facet=products&%24filter=scopes%2Fany%28t%3A+t+eq+%27WebView2%27%29";
# First we fill in the template with a URI encoded string of the language, space, API name
# For example, "WinRT CoreWebView2Environment" becomes "WinRT+CoreWebView2Environment"
$encodedQuery = [System.Web.HttpUtility]::UrlEncode("$Language $Api");
# Then we resolve the template to a URI using that query
$msdnSearchRssUri = $msdnSearchRssUriTemplate -f $encodedQuery;
# Next we perform a web request to that URI
$msdnSearchRss = Invoke-WebRequest -Uri $msdnSearchRssUri;
# And get the XML content of the HTTP response body out of that
$msdnSearchRssXml = [xml]$msdnSearchRss.Content;
function MatchStrength($result, $request) {
$entryTitleLower = $result.ToLower();
$apiLower = $request.ToLower();
# Exact match wins
if ($entryTitleLower -eq $apiLower) {
0;
} # Otherwise if it exists as a single word in the title thats great
elseif ($entryTitleLower -like "* $apiLower *") {
1;
} # Or if it exists not as a single word but as a suffix
elseif ($entryTitleLower -like "*$apiLower *") {
2;
} # Or a prefix
elseif ($entryTitleLower -like "* $apiLower*") {
3;
} # Or just in there somewhere
elseif ($entryTitleLower -contains $apiLower) {
4;
}
else { # Otherwise...
5;
}
}
$languageToPathPart = @{
"WinRT" = "/reference/winrt/";
"DotNet" = "/dotnet/api/";
"Win32" = "/reference/win32/";
};
# Convert the RSS items into PowerShell objects with a Title property, Uri property, Language property, and MatchStrength property
# The MatchStrength property is a number that indicates how good of a match the result is where
# 0 is the best and higher numbers are worse
$results = $msdnSearchRssXml.rss.channel.item | ForEach-Object {
$titleProperty = $_.title;
$uriProperty = $_.link;
$linkProperty = (Format-TerminalClickableString $_.link $_.title);
$languageProperty = "Unknown";
# Use languageToPathPart to determine which language the link is for
foreach ($key in $languageToPathPart.Keys) {
if ($uriProperty -like "*$($languageToPathPart[$key])*") {
$languageProperty = $key;
break;
}
}
$matchStrengthProperty = MatchStrength $titleProperty $Api;
New-Object PSObject -Property @{
Title = $titleProperty;
Uri = $uriProperty;
Link = $linkProperty;
Language = $languageProperty;
MatchStrength = $matchStrengthProperty;
};
}
$resultsFiltered = $results | Where-Object { $_.Language -eq $Language -or $Language -eq "Unknown" };
# Now sort the results for better matches first
# Titles that contain the API name are better matches than those that don't
$resultsFilteredSorted = $resultsFiltered | Sort-Object -Property MatchStrength;
if (!$All -and $resultsFilteredSorted.Count -gt 1) {
$bestMatchStrength = $resultsFilteredSorted[0].MatchStrength;
$resultsFilteredSorted = $resultsFilteredSorted | Where-Object { $_.MatchStrength -eq $bestMatchStrength };
}
if (!$WhatIf) {
# Open default browser with the first result
$firstResult = $resultsFilteredSorted[0];
Start-Process $firstResult.Uri;
} else {
# List all results as PowerShell objects with title, uri, and
# link which is the Title text but uses Unix escape sequence to
# make it a link to Uri
if ($Language -eq "Unknown") {
$resultsFilteredSorted | Format-Table -Property Language,Link;
} else {
$resultsFilteredSorted | Format-Table -Property Link;
}
}
}
function GetBrowserProcesses {
[cmdletbinding()]
param(
[string] $CommandLineMatch = "",
[ValidateSet("All", "Canary", "Dev", "Beta", "Stable")]
[string[]] $Channels = @("All"),
[ValidateSet("Chromium", "Chrome", "Edge", "WebView2")]
[string[]] $HostKinds = @("Chromium", "Chrome", "Edge", "WebView2"),
[ValidateSet("All", "browser", "crashpad-handler", "gpu-process", "renderer", "utility")]
[string[]] $ProcessKinds = @("All"),
[switch] [alias("np")] $NoPretty
);
# Get-Process's CommandLine property is slow because it uses individual calls to Get-CimInstance.
# We can speed it up a bunch by running Get-CimInstance ourselves for all the processes we're
# interested in.
$cimProcesses = @();
$processes = @();
if ($HostKinds.Contains("Chrome") -or $HostKinds.Contains("Chromium")) {
$processes += Get-Process chrome -ErrorAction SilentlyContinue;
$cimProcesses += Get-cimInstance Win32_Process -Filter "Name='chrome.exe'";
}
if ($HostKinds.Contains("Edge")) {
$processes += Get-Process msedge -ErrorAction SilentlyContinue;
$cimProcesses += Get-cimInstance Win32_Process -Filter "Name='msedge.exe'";
}
if ($HostKinds.Contains("WebView2")) {
$processes += Get-Process msedgewebview2 -ErrorAction SilentlyContinue;
$cimProcesses += Get-cimInstance Win32_Process -Filter "Name='msedgewebview2.exe'";
}
$processes = $processes | ForEach-Object {
$currentProcess = $_;
$MainModulePath = $_.MainModule.FileName.ToLower();
[void]($currentProcess | Add-Member MainModulePath $MainModulePath);
$HostKind = "Edge";
if ($_.ProcessName -eq "msedge") {
$HostKind = "Edge";
} elseif ($_.ProcessName -eq "chrome") {
if ($_.Product -eq "Chromium") {
$HostKind = "Chromium";
} else {
$HostKind = "Chrome";
}
} else {
$HostKind = "WebView2";
}
# Since chromium and chrome share the same executable name,
# Check if the HostKind doesn't match the HostKinds and if so
# skip this one
if (-not ($HostKinds -contains $HostKind)) {
return;
}
[void]($currentProcess | Add-Member HostKind $HostKind);
$Channel = "Unknown";
if ($MainModulePath.Contains("\edge sxs\") -or $MainModulePath.Contains("\chrome SxS\application\")) {
$Channel = "Canary";
} elseif ($MainModulePath.Contains("\edge beta\") -or $MainModulePath.Contains("\chrome beta\application\")) {
$Channel = "Beta";
} elseif ($MainModulePath.Contains("\edge dev\") -or $MainModulePath.Contains("\chrome dev\application\")) {
$Channel = "Dev";
} elseif ($MainModulePath.Contains("\edge\") -or $MainModulePath.Contains("\edgewebview\") -or $MainModulePath.Contains("\chrome\application\")) {
$Channel = "Stable";
}
[void]($currentProcess | Add-Member Channel $Channel);
$currentProcessKind = "browser";
$currentCommandLine = ($cimProcesses | Where-Object {
$_.ProcessId -eq $currentProcess.Id
}).CommandLine;
if ($currentCommandLine -match "--type=([^ ]+)") {
$currentProcessKind = $Matches[1];
}
$version = (Get-Item $MainModulePath).VersionInfo.FileVersion;
[void]($currentProcess | Add-Member ProcessKind $currentProcessKind);
[void]($currentProcess | Add-Member -Force EdgeCommandLine $currentCommandLine);
[void]($currentProcess | Add-Member -Force Version $version);
$currentProcess;
}
$processes = $processes | Where-Object {
$currentProcess = $_;
$channelMatches = $Channels -contains $currentProcess.Channel -or $Channels -contains "All";
$edgeProcessTypeMatches = $ProcessKinds -contains $currentProcess.ProcessKind -or $ProcessKinds -contains "All";
$commandLineMatches = $CommandLineMatch -eq "" -or $currentProcess.EdgeCommandLine -match $CommandLineMatch;
$channelMatches -and $edgeProcessTypeMatches -and $commandLineMatches;
};
if ($NoPretty) {
$processes;
} else {
$processes | `
Sort-Object HostKind,MainModulePath,Version,Channel,ProcessKind,Id | `
Format-Table HostKind,Version,Channel,ProcessKind,Id,EdgeCommandLine;
}
}
New-Alias -f Get-BrowserProcesses GetBrowserProcesses;