@yxzpro/agent-acta 2.14.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/LOGFORMATS.md +960 -0
- package/README.md +238 -0
- package/REFERENCE.md +1428 -0
- package/agent-acta-page.html +1998 -0
- package/agent-acta-server.mjs +1066 -0
- package/agent-acta-widget.html +724 -0
- package/archive.mjs +335 -0
- package/core/log.mjs +20 -0
- package/core/service.mjs +4285 -0
- package/hooks/cursor-usage-hook.mjs +89 -0
- package/mcp-server.mjs +372 -0
- package/package.json +68 -0
- package/page/dialog-add-agent.js +65 -0
- package/page/dialog-alert.js +159 -0
- package/page/dialog-archive.js +342 -0
- package/page/dialog-compare.js +238 -0
- package/page/dialog-ctxw.js +101 -0
- package/page/dialog-diag.js +72 -0
- package/page/dialog-heatmap.js +215 -0
- package/page/dialog-selftest.js +202 -0
- package/page/dialog-sess-timeline.js +108 -0
- package/page/dialog-stats.js +694 -0
- package/page/dialog-usage.js +158 -0
- package/page/log-card.js +277 -0
- package/page/log-view.js +273 -0
- package/page/sess-view.js +382 -0
- package/page/shared.js +408 -0
- package/page/sidebar.js +129 -0
- package/page/style.css +973 -0
- package/page/topbar.js +61 -0
- package/parsers/atomcode.mjs +321 -0
- package/parsers/buddy.mjs +272 -0
- package/parsers/buddyext.mjs +582 -0
- package/parsers/claude.mjs +496 -0
- package/parsers/cline.mjs +468 -0
- package/parsers/codearts.mjs +96 -0
- package/parsers/codex.mjs +188 -0
- package/parsers/comate.mjs +195 -0
- package/parsers/copilot.mjs +308 -0
- package/parsers/cursor.mjs +493 -0
- package/parsers/devindb.mjs +358 -0
- package/parsers/discovery.mjs +1230 -0
- package/parsers/doubao.mjs +406 -0
- package/parsers/dsh.mjs +377 -0
- package/parsers/gemini.mjs +267 -0
- package/parsers/generic.mjs +494 -0
- package/parsers/hermes.mjs +398 -0
- package/parsers/kilo.mjs +42 -0
- package/parsers/kimi.mjs +249 -0
- package/parsers/mimocode.mjs +531 -0
- package/parsers/minimax.mjs +503 -0
- package/parsers/openclaw.mjs +490 -0
- package/parsers/opencode.mjs +465 -0
- package/parsers/shared.mjs +418 -0
- package/parsers/trace.mjs +66 -0
- package/parsers/tracecode.mjs +348 -0
- package/parsers/traedb.mjs +528 -0
- package/parsers/zcode.mjs +356 -0
- package/plugin/client.js +51 -0
- package/plugin/cordis.patch.yml +5 -0
- package/plugin/plugin.mjs +220 -0
- package/search.mjs +554 -0
- package/tools/grab-trae-key.ps1 +265 -0
- package/vendor/element-plus-icons.js +3 -0
- package/vendor/element-plus.css +1 -0
- package/vendor/element-plus.dark.css +1 -0
- package/vendor/element-plus.full.min.js +65 -0
- package/vendor/element-plus.zh-cn.js +2 -0
- package/vendor/svg/antgroup-color.svg +1 -0
- package/vendor/svg/bytedance-color.svg +1 -0
- package/vendor/svg/chatglm-color.svg +1 -0
- package/vendor/svg/claude-color.svg +1 -0
- package/vendor/svg/claudecode-color.svg +1 -0
- package/vendor/svg/cline.svg +1 -0
- package/vendor/svg/codebuddy-color.svg +1 -0
- package/vendor/svg/codebuddy.svg +1 -0
- package/vendor/svg/codex-color.svg +1 -0
- package/vendor/svg/copilot.svg +1 -0
- package/vendor/svg/cursor.svg +1 -0
- package/vendor/svg/deepseek-color.svg +1 -0
- package/vendor/svg/deepseek-harness-whale.svg +8 -0
- package/vendor/svg/doubao-color.svg +1 -0
- package/vendor/svg/gemini-color.svg +1 -0
- package/vendor/svg/glmv-color.svg +1 -0
- package/vendor/svg/grok.svg +1 -0
- package/vendor/svg/hermesagent.svg +1 -0
- package/vendor/svg/huawei-color.svg +1 -0
- package/vendor/svg/hunyuan-color.svg +1 -0
- package/vendor/svg/kilocode-avatar.svg +1 -0
- package/vendor/svg/kilocode.svg +1 -0
- package/vendor/svg/kimi-color.svg +1 -0
- package/vendor/svg/kimi.svg +1 -0
- package/vendor/svg/logo-AtomGit-G-red.svg +3 -0
- package/vendor/svg/logo-AtomGit-dark.svg +4 -0
- package/vendor/svg/logo-AtomGit-light.svg +4 -0
- package/vendor/svg/meta-color.svg +1 -0
- package/vendor/svg/mimo.svg +66 -0
- package/vendor/svg/minimax-code-logo.svg +8 -0
- package/vendor/svg/minimax-color.svg +1 -0
- package/vendor/svg/moonshot.svg +1 -0
- package/vendor/svg/nex-color.svg +1 -0
- package/vendor/svg/nex.svg +1 -0
- package/vendor/svg/nvidia-color.svg +1 -0
- package/vendor/svg/openai.svg +1 -0
- package/vendor/svg/openclaw-color.svg +1 -0
- package/vendor/svg/openclaw.svg +1 -0
- package/vendor/svg/opencode.svg +1 -0
- package/vendor/svg/openrouter-color.svg +1 -0
- package/vendor/svg/qoder-color.svg +1 -0
- package/vendor/svg/qwen-color.svg +1 -0
- package/vendor/svg/sensenova-color.svg +1 -0
- package/vendor/svg/stepfun.svg +1 -0
- package/vendor/svg/trae-color.svg +1 -0
- package/vendor/svg/traework-v2.svg +1 -0
- package/vendor/svg/wenxin-color.svg +1 -0
- package/vendor/svg/windsurf.svg +1 -0
- package/vendor/svg/workbuddy-color.svg +29 -0
- package/vendor/svg/xiaomimimo.svg +1 -0
- package/vendor/svg/yuanbao-color.svg +1 -0
- package/vendor/svg/yuanbao.svg +1 -0
- package/vendor/svg/zai.svg +1 -0
- package/vendor/svg/zhipu-color.svg +1 -0
- package/vendor/vue.global.prod.js +9 -0
- package/widget/main.js +202 -0
- package/widget/package.json +7 -0
- package/widget/preload.js +11 -0
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
# grab-trae-key.ps1 — capture the SQLCipher key (traeKey) of Trae CN / Trae Work
|
|
2
|
+
# from the AI host process memory, for agentLog's traedb source.
|
|
3
|
+
#
|
|
4
|
+
# Usage (Trae must be running):
|
|
5
|
+
# powershell -ExecutionPolicy Bypass -File grab-trae-key.ps1
|
|
6
|
+
# powershell -ExecutionPolicy Bypass -File grab-trae-key.ps1 -Minutes 10 -NoElevate
|
|
7
|
+
#
|
|
8
|
+
# -OutFile <path> machine-readable mode (used by the agentLog page button):
|
|
9
|
+
# write a one-line JSON result {ok, key?, error?, message?} to <path>.
|
|
10
|
+
# The elevated relaunch gets -OutFile too (its stdout is not
|
|
11
|
+
# readable by the parent), and the script never waits for Enter.
|
|
12
|
+
param(
|
|
13
|
+
[int]$Minutes = 5,
|
|
14
|
+
[switch]$NoElevate,
|
|
15
|
+
[string]$OutFile = ''
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
# How it works:
|
|
19
|
+
# 1. Sweep every Trae* process unelevated (~20s). If the key string is visible, done.
|
|
20
|
+
# 2. Otherwise it relaunches itself elevated (one UAC prompt). The AI host process
|
|
21
|
+
# denies PROCESS_VM_READ to unelevated callers (Trae ships an anti-tamper DLL),
|
|
22
|
+
# so admin rights are required for the real deal.
|
|
23
|
+
# 3. The scanner looks for the SQLCipher statement the sqlx runtime builds:
|
|
24
|
+
# PRAGMA key = "x'<64 hex>'";
|
|
25
|
+
# That string stays resident in the host process heap for hours once the app
|
|
26
|
+
# has opened its database, so a plain memory sweep finds it.
|
|
27
|
+
# 4. If nothing shows up: open Trae CN and send one AI chat message (that opens
|
|
28
|
+
# the DB), or restart Trae CN while this scanner keeps running.
|
|
29
|
+
|
|
30
|
+
$ErrorActionPreference = 'Stop'
|
|
31
|
+
$isAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
|
32
|
+
|
|
33
|
+
$src = @'
|
|
34
|
+
using System;
|
|
35
|
+
using System.Text;
|
|
36
|
+
using System.Collections.Generic;
|
|
37
|
+
using System.Runtime.InteropServices;
|
|
38
|
+
|
|
39
|
+
public class TraeKeyGrab {
|
|
40
|
+
[DllImport("kernel32.dll")] static extern IntPtr OpenProcess(uint access, bool inherit, int pid);
|
|
41
|
+
[DllImport("kernel32.dll")] static extern bool CloseHandle(IntPtr h);
|
|
42
|
+
[DllImport("kernel32.dll")] static extern int VirtualQueryEx(IntPtr h, IntPtr addr, out MEMORY_BASIC_INFORMATION64 mbi, UIntPtr len);
|
|
43
|
+
[DllImport("kernel32.dll")] static extern bool ReadProcessMemory(IntPtr h, IntPtr addr, byte[] buf, UIntPtr size, out UIntPtr read);
|
|
44
|
+
|
|
45
|
+
[StructLayout(LayoutKind.Sequential)]
|
|
46
|
+
public struct MEMORY_BASIC_INFORMATION64 {
|
|
47
|
+
public ulong BaseAddress; public ulong AllocationBase; public uint AllocationProtect;
|
|
48
|
+
public uint __align1; public ulong RegionSize; public uint State; public uint Protect; public uint Type; public uint __align2;
|
|
49
|
+
}
|
|
50
|
+
const uint PROCESS_VM_READ = 0x10, PROCESS_QUERY_INFORMATION = 0x400;
|
|
51
|
+
const uint MEM_COMMIT = 0x1000;
|
|
52
|
+
const uint PAGE_NOACCESS = 0x01, PAGE_GUARD = 0x100;
|
|
53
|
+
const int CHUNK = 8 * 1024 * 1024, OVERLAP = 512;
|
|
54
|
+
|
|
55
|
+
static byte[][] markers = new byte[][] {
|
|
56
|
+
Encoding.ASCII.GetBytes("PRAGMA key = \"x'"),
|
|
57
|
+
Encoding.ASCII.GetBytes("PRAGMA key = 'x"),
|
|
58
|
+
Encoding.ASCII.GetBytes("PRAGMA key = x'"),
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
// Returns the candidate key strings found in the process. openErr != null means
|
|
62
|
+
// the process could not be opened for reading.
|
|
63
|
+
public static List<string> Scan(int pid, out string openErr) {
|
|
64
|
+
openErr = null;
|
|
65
|
+
var found = new List<string>();
|
|
66
|
+
IntPtr h = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, false, pid);
|
|
67
|
+
if (h == IntPtr.Zero) { openErr = "access denied"; return found; }
|
|
68
|
+
ulong addr = 0;
|
|
69
|
+
while (addr < 0x7FFFFFFFFFFF) {
|
|
70
|
+
MEMORY_BASIC_INFORMATION64 mbi;
|
|
71
|
+
if (VirtualQueryEx(h, (IntPtr)addr, out mbi, (UIntPtr)Marshal.SizeOf(typeof(MEMORY_BASIC_INFORMATION64))) == 0) break;
|
|
72
|
+
bool readable = mbi.State == MEM_COMMIT && (mbi.Protect & (PAGE_NOACCESS | PAGE_GUARD)) == 0;
|
|
73
|
+
bool isImage = mbi.Type == 0x1000000;
|
|
74
|
+
if (readable && !isImage && mbi.RegionSize > 0) {
|
|
75
|
+
ulong pos = mbi.BaseAddress, end = mbi.BaseAddress + mbi.RegionSize;
|
|
76
|
+
while (pos < end) {
|
|
77
|
+
ulong rest = end - pos;
|
|
78
|
+
int want = (int)Math.Min((ulong)CHUNK, rest);
|
|
79
|
+
bool tail = (ulong)want < rest;
|
|
80
|
+
byte[] buf = new byte[want + (tail ? OVERLAP : 0)];
|
|
81
|
+
UIntPtr read;
|
|
82
|
+
if (ReadProcessMemory(h, (IntPtr)pos, buf, (UIntPtr)buf.Length, out read) && (ulong)read > 0) {
|
|
83
|
+
int len = (int)(ulong)read;
|
|
84
|
+
foreach (var mk in markers) {
|
|
85
|
+
int i = 0;
|
|
86
|
+
while (true) {
|
|
87
|
+
i = IndexOf(buf, mk, len, i);
|
|
88
|
+
if (i < 0) break;
|
|
89
|
+
var sb = new StringBuilder();
|
|
90
|
+
for (int j = i; j < len && j < i + 200; j++) { byte c = buf[j]; if (c < 0x20 || c > 0x7e) break; sb.Append((char)c); }
|
|
91
|
+
string s = sb.ToString();
|
|
92
|
+
if (s.Length > mk.Length + 64 && !s.Contains("@.") && !found.Contains(s)) found.Add(s);
|
|
93
|
+
i += mk.Length;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
pos += (ulong)want;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
ulong next = mbi.BaseAddress + mbi.RegionSize;
|
|
101
|
+
if (next <= addr) break;
|
|
102
|
+
addr = next;
|
|
103
|
+
}
|
|
104
|
+
CloseHandle(h);
|
|
105
|
+
return found;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
static int IndexOf(byte[] hay, byte[] needle, int len, int from) {
|
|
109
|
+
int limit = Math.Min(len, hay.Length) - needle.Length;
|
|
110
|
+
for (int i = from; i <= limit; i++) {
|
|
111
|
+
bool ok = true;
|
|
112
|
+
for (int j = 0; j < needle.Length; j++) if (hay[i + j] != needle[j]) { ok = false; break; }
|
|
113
|
+
if (ok) return i;
|
|
114
|
+
}
|
|
115
|
+
return -1;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
'@
|
|
119
|
+
|
|
120
|
+
Add-Type -TypeDefinition $src -ReferencedAssemblies System
|
|
121
|
+
|
|
122
|
+
function Get-TraePids {
|
|
123
|
+
@(Get-Process -ErrorAction SilentlyContinue |
|
|
124
|
+
Where-Object { $_.ProcessName -match '(?i)trae|agent-tool|harness' } |
|
|
125
|
+
Select-Object -ExpandProperty Id)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function Get-KeyFromPid([int]$pid_, [ref]$why) {
|
|
129
|
+
$why.Value = ''
|
|
130
|
+
$key = $null
|
|
131
|
+
$err = $null
|
|
132
|
+
try { $hits = [TraeKeyGrab]::Scan($pid_, [ref]$err) } catch { $why.Value = 'scan error'; return $null }
|
|
133
|
+
if ($err) { $why.Value = $err; return $null }
|
|
134
|
+
foreach ($s in $hits) {
|
|
135
|
+
$m = [regex]::Match($s, "x'([0-9a-fA-F]{64})'")
|
|
136
|
+
if ($m.Success) { $key = $m.Groups[1].Value.ToLower(); $why.Value = "hit: $s"; break }
|
|
137
|
+
}
|
|
138
|
+
if (-not $key) { $why.Value = 'no key string' }
|
|
139
|
+
return $key
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function Show-Result([string]$key) {
|
|
143
|
+
Write-Host ''
|
|
144
|
+
Write-Host '================================================================'
|
|
145
|
+
Write-Host ' traeKey (SQLCipher key for Trae):'
|
|
146
|
+
Write-Host ''
|
|
147
|
+
Write-Host " $key"
|
|
148
|
+
Write-Host ''
|
|
149
|
+
Write-Host ' (also copied to clipboard)'
|
|
150
|
+
Write-Host ' Paste it into the agentLog config, trae entry "traeKey" field:'
|
|
151
|
+
Write-Host " $(Join-Path $env:USERPROFILE '.agent-log\config.json')"
|
|
152
|
+
Write-Host '================================================================'
|
|
153
|
+
Write-Host ''
|
|
154
|
+
try { Set-Clipboard -Value $key } catch {}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
# 服务器模式(-OutFile):把结构化结果写成一行 JSON。提权实例的 stdout 父进程收不到,
|
|
158
|
+
# 只有这个文件能把「抓到没有 / 为什么没抓到」带回给服务端(服务端读后即删)。
|
|
159
|
+
function Write-Result([bool]$ok, [string]$code, [string]$message, [string]$key) {
|
|
160
|
+
if (-not $OutFile) { return }
|
|
161
|
+
$obj = @{ ok = $ok }
|
|
162
|
+
if ($key) { $obj['key'] = $key }
|
|
163
|
+
if ($code) { $obj['error'] = $code }
|
|
164
|
+
if ($message) { $obj['message'] = $message }
|
|
165
|
+
try {
|
|
166
|
+
$json = $obj | ConvertTo-Json -Compress
|
|
167
|
+
[IO.File]::WriteAllText($OutFile, $json, (New-Object System.Text.UTF8Encoding($false)))
|
|
168
|
+
} catch {}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
$script:traeSeen = $false # 这次运行里出现过 Trae 进程吗(区分失败原因:没有 Trae / 有 Trae 但没抓到)
|
|
172
|
+
|
|
173
|
+
function New-Sweep([int]$seconds) {
|
|
174
|
+
$deadline = (Get-Date).AddSeconds($seconds)
|
|
175
|
+
$announced = $false
|
|
176
|
+
while ((Get-Date) -lt $deadline) {
|
|
177
|
+
$pids = Get-TraePids # 每轮重取:Trae 可能刚开始启动(从页面点完按钮才去开 Trae 是常态)
|
|
178
|
+
if ($pids.Count -eq 0) {
|
|
179
|
+
if (-not $announced) { Write-Host 'No Trae process yet - waiting for Trae CN to start...'; $announced = $true }
|
|
180
|
+
} else {
|
|
181
|
+
$script:traeSeen = $true
|
|
182
|
+
if (-not $announced) { Write-Host ("Trae processes: " + ($pids -join ', ') + " (admin: $isAdmin)"); $announced = $true }
|
|
183
|
+
foreach ($p in $pids) {
|
|
184
|
+
$why = ''
|
|
185
|
+
$key = Get-KeyFromPid $p ([ref]$why)
|
|
186
|
+
$tag = if ($why -eq 'access denied') { 'blocked (needs admin)' } else { $why }
|
|
187
|
+
Write-Host (" pid $p : $tag")
|
|
188
|
+
if ($key) { return $key }
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
Start-Sleep -Seconds 2
|
|
192
|
+
}
|
|
193
|
+
return $null
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
try {
|
|
197
|
+
Write-Host '=== grab-trae-key: Trae SQLCipher key capture ==='
|
|
198
|
+
|
|
199
|
+
# Phase 1: quick unelevated sweep. The AI host process may or may not expose the
|
|
200
|
+
# string without elevation; some machines/processes do.
|
|
201
|
+
$key = New-Sweep -seconds 20
|
|
202
|
+
|
|
203
|
+
if (-not $key -and -not $isAdmin -and -not $NoElevate) {
|
|
204
|
+
if (-not $script:traeSeen) {
|
|
205
|
+
# 连一个 Trae 进程都没有:提权也无事可做,直接给结论(别再白弹一次 UAC)
|
|
206
|
+
Write-Host 'No Trae process found. Open Trae CN first (and use the AI chat once).'
|
|
207
|
+
} else {
|
|
208
|
+
Write-Host ''
|
|
209
|
+
Write-Host 'Trae host process denies memory reads to non-admin users (anti-tamper).'
|
|
210
|
+
Write-Host 'Relaunching this script as administrator (one UAC prompt)...'
|
|
211
|
+
Write-Host 'While it scans: open Trae CN and send one AI chat message, or restart Trae CN.'
|
|
212
|
+
$args_ = @('-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', "`"$PSCommandPath`"", '-Minutes', "$Minutes")
|
|
213
|
+
if ($OutFile) { $args_ += @('-OutFile', "`"$OutFile`"") }
|
|
214
|
+
$proc_ = $null
|
|
215
|
+
try {
|
|
216
|
+
$proc_ = Start-Process -FilePath 'powershell.exe' -Verb RunAs -ArgumentList $args_ -PassThru
|
|
217
|
+
} catch {
|
|
218
|
+
Write-Host "Elevation failed or was canceled: $($_.Exception.Message)"
|
|
219
|
+
Write-Result $false 'elevation-canceled' $_.Exception.Message $null
|
|
220
|
+
}
|
|
221
|
+
if ($OutFile) {
|
|
222
|
+
if (-not $proc_) {
|
|
223
|
+
# 取消 UAC 在 PS 5.1 里有时既不抛异常也不返回进程对象 —— 只能这样认出来。
|
|
224
|
+
# 认不出来就会让服务端干等 5 分钟,所以这一步不能省。
|
|
225
|
+
Write-Host 'Elevation did not start (UAC was canceled).'
|
|
226
|
+
Write-Result $false 'elevation-canceled' '' $null
|
|
227
|
+
} else {
|
|
228
|
+
# 服务端以「本进程退出」为完成信号,所以提权接管之后本进程不能先走:
|
|
229
|
+
# 等结果文件出现(提权实例写完即退),最多等到它的扫描窗口 + 2 分钟余量。
|
|
230
|
+
$waitUntil = (Get-Date).AddSeconds($Minutes * 60 + 120)
|
|
231
|
+
while ((Get-Date) -lt $waitUntil -and -not (Test-Path -LiteralPath $OutFile)) {
|
|
232
|
+
Start-Sleep -Seconds 2
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
exit
|
|
237
|
+
}
|
|
238
|
+
} elseif (-not $key) {
|
|
239
|
+
Write-Host ''
|
|
240
|
+
Write-Host "Key not found yet. Keep scanning for $Minutes minute(s)."
|
|
241
|
+
Write-Host 'Trigger the DB open in Trae: send one AI chat message, or restart Trae CN.'
|
|
242
|
+
$key = New-Sweep -seconds ($Minutes * 60)
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if ($key) {
|
|
246
|
+
Show-Result $key
|
|
247
|
+
Write-Result $true '' '' $key
|
|
248
|
+
} else {
|
|
249
|
+
$code = if ($script:traeSeen) { 'no-key' } else { 'no-trae-process' }
|
|
250
|
+
Write-Host ''
|
|
251
|
+
Write-Host 'No key found. Checklist:'
|
|
252
|
+
Write-Host ' 1. Trae CN is running and you have used the AI chat at least once.'
|
|
253
|
+
Write-Host ' 2. Run this script as administrator (right-click > Run as administrator).'
|
|
254
|
+
Write-Host ' 3. Try again right after restarting Trae CN.'
|
|
255
|
+
Write-Result $false $code '' $null
|
|
256
|
+
}
|
|
257
|
+
} catch {
|
|
258
|
+
Write-Host "ERROR: $($_.Exception.Message)"
|
|
259
|
+
Write-Result $false 'scan-error' $_.Exception.Message $null
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
if (($isAdmin -or $NoElevate) -and -not $OutFile) {
|
|
263
|
+
Write-Host 'Press Enter to close...'
|
|
264
|
+
[void](Read-Host)
|
|
265
|
+
}
|