-
-
Notifications
You must be signed in to change notification settings - Fork 21
/
Invoke-Ngen.ps1
163 lines (138 loc) · 4.48 KB
/
Invoke-Ngen.ps1
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
<#PSScriptInfo
.VERSION 1.0.2
.AUTHOR Roman Kuzmin
.COPYRIGHT (c) Roman Kuzmin
.TAGS Performance Tool Ngen
.GUID dcdd1d48-3113-4b90-9842-d9eae293d897
.PROJECTURI https://github.com/nightroman/PowerShelf
.LICENSEURI http://www.apache.org/licenses/LICENSE-2.0
#>
<#
.Synopsis
Invokes the Native Image Generator tool (ngen.exe).
.Description
Use this tool to improve performance of managed applications. It creates
native images and installs them into the native image cache. The runtime
can use native images from the cache instead of using the just-in-time
(JIT) compiler to compile original assemblies.
The tool may print various errors "Failed to load dependency..." and etc.
They are not necessarily problems, the tool still improves what it can.
.Parameter Alias
Tells to set the alias `ngen` in the calling scope.
Use the alias in order to call the tool directly.
Example:
ngen /?
.Parameter Update
Tells to update native images that have become invalid. Without -Queue
this operation may take several minutes. But you may see some improved
performance immediately after that.
If -Queue is specified, the updates are queued for the ngen service and
the command finishes immediately. Updates run when the computer is idle.
.Parameter Queue
Tells to queue updates for the ngen service. It is used with -Update.
.Parameter Directory
Specifies the directory and tells to generate native images for its
exe and dll files.
.Parameter Recurse
With -Directory, tells to include child directories and sets
-NoDependencies to true.
.Parameter Current
Tells to generate native images for the currently loaded app assemblies.
Of course, it is a PowerShell hosting app, either console or another host.
.Parameter NoDependencies
With -Directory or -Current, tells to generate the minimum number of
native images required. With -Recurse, tt is ignored and used as true.
.Example
>
# update native images in the local computer cache
Invoke-Ngen -Update
# generate images for exe and dll from a directory
Invoke-Ngen -Directory . -Recurse
.Link
https://docs.microsoft.com/en-us/dotnet/framework/tools/ngen-exe-native-image-generator
.Link
https://github.com/nightroman/PowerShelf
#>
[CmdletBinding(DefaultParameterSetName='Usage')]
param(
[Parameter(Mandatory=1, ParameterSetName = 'Alias')]
[switch]$Alias
,
[Parameter(Mandatory=1, ParameterSetName = 'Update')]
[switch]$Update
,
[Parameter(ParameterSetName = 'Update')]
[switch]$Queue
,
[Parameter(Mandatory=1, ParameterSetName = 'Current')]
[switch]$Current
,
[Parameter(Mandatory=1, ParameterSetName = 'Directory')]
[string]$Directory
,
[Parameter(ParameterSetName = 'Directory')]
[switch]$Recurse
,
[Parameter(ParameterSetName = 'Current')]
[Parameter(ParameterSetName = 'Directory')]
[switch]$NoDependencies
)
$ErrorActionPreference = 1
trap { Write-Error $_ }
if ($PSVersionTable.PSEdition -eq 'Core') {
$ngen = powershell -NoProfile -Command 'Join-Path ([Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory()) ngen.exe'
}
else {
$ngen = Join-Path ([Runtime.InteropServices.RuntimeEnvironment]::GetRuntimeDirectory()) ngen.exe
}
if (!$ngen -or !(Test-Path -LiteralPath $ngen)) {
throw "Cannot find ngen.exe"
}
if ($PSCmdlet.ParameterSetName -eq 'Alias') {
Set-Alias ngen $ngen -Scope 1
return
}
Set-Alias ngen $ngen
if ($PSCmdlet.ParameterSetName -eq 'Update') {
if ($Queue) {
ngen update /queue
}
else {
ngen update
}
return
}
if ($PSCmdlet.ParameterSetName -eq 'Current') {
foreach($_ in [AppDomain]::CurrentDomain.GetAssemblies()) {
Write-Host $_.Location -ForegroundColor Cyan
if ($NoDependencies) {
ngen install $_.Location /NoDependencies /nologo
}
else {
ngen install $_.Location /nologo
}
}
return
}
if ($PSCmdlet.ParameterSetName -eq 'Directory') {
$Directory = $PSCmdlet.GetUnresolvedProviderPathFromPSPath($Directory)
Get-ChildItem -LiteralPath $Directory -Recurse:$Recurse | .{process{
if ($_.Extension -match '\.(exe|dll)$') {
Write-Host $_.FullName -ForegroundColor Cyan
if ($NoDependencies -or $Recurse) {
ngen install $_.FullName /NoDependencies /nologo
}
else {
ngen install $_.FullName /nologo
}
}
}}
return
}
Write-Host @'
Usage:
Invoke-Ngen -Alias
Invoke-Ngen -Update [-Queue]
Invoke-Ngen -Current [-NoDependencies]
Invoke-Ngen -Directory <path> [-Recurse] [-NoDependencies]
'@