XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
[CmdletBinding()]
param([Parameter(Mandatory)][string]$Label,[ValidateRange(30,180)][int]$Seconds=60)
$ErrorActionPreference='Stop'
$taskGame='D:\SteamLibrary\steamapps\common\Elite Dangerous\Products\elite-dangerous-odyssey-64\EliteDangerous64.exe'
$taskLauncher='D:\SteamLibrary\steamapps\common\Elite Dangerous\EDLaunch.exe'
$taskRoot=Split-Path -Parent $PSScriptRoot
$taskOutput=Join-Path $taskRoot ('artifacts\crash-analysis-20261021\startup-'+$Label+'.json')
if($Label -notmatch '^[a-zA-Z0-9-]+$' -or (Test-Path -LiteralPath $taskOutput)){throw 'Use a new simple evidence label.'}
if(Get-CimInstance Win32_Process -Filter "Name='EliteDangerous64.exe'" | Where-Object {$_.ExecutablePath -eq $taskGame}){throw 'The selected game is already running.'}
$taskBegin=Get-Date
foreach($taskOldLauncher in (Get-CimInstance Win32_Process -Filter "Name='EDLaunch.exe'" | Where-Object {$_.ExecutablePath -eq $taskLauncher})){
    $taskProcess=Get-Process -Id $taskOldLauncher.ProcessId
    if(-not $taskProcess.CloseMainWindow() -or -not $taskProcess.WaitForExit(15000)){throw 'The existing official launcher did not close normally.'}
}
$taskFiles=@('EliteDangerous64.exe','dinput8.dll','dbghelp.dll','edchs.pkg') | ForEach-Object {
    $taskPath=Join-Path (Split-Path -Parent $taskGame) $_
    if(Test-Path -LiteralPath $taskPath){[ordered]@{name=$_;sha256=(Get-FileHash -LiteralPath $taskPath -Algorithm SHA256).Hash.ToLowerInvariant()}}
}
$taskStart=[Diagnostics.ProcessStartInfo]::new($taskLauncher)
$taskStart.UseShellExecute=$false
$taskStart.WorkingDirectory=Split-Path -Parent $taskLauncher
$taskStart.WindowStyle=[Diagnostics.ProcessWindowStyle]::Hidden
$taskStart.Environment['SteamAppId']='359320'
$taskStart.Environment['SteamGameId']='359320'
foreach($taskArgument in @('/Steam','/autorun','/autoquit','/novr','/select','odyssey')){$taskStart.ArgumentList.Add($taskArgument)}
$taskLaunched=[Diagnostics.Process]::Start($taskStart)
$taskLaunched.Dispose()
$taskSelected=$null
$taskDeadline=(Get-Date).AddSeconds(45)
while((Get-Date) -lt $taskDeadline -and -not $taskSelected){
    $taskSelected=Get-CimInstance Win32_Process -Filter "Name='EliteDangerous64.exe'" | Where-Object {$_.ExecutablePath -eq $taskGame -and $_.CreationDate -ge $taskBegin} | Select-Object -First 1
    if(-not $taskSelected){Start-Sleep -Milliseconds 500}
}
$taskSamples=[Collections.Generic.List[object]]::new()
$taskSurvived=$false
if($taskSelected){
    $taskDeadline=(Get-Date).AddSeconds($Seconds)
    while((Get-Date) -lt $taskDeadline){
        $taskProcess=Get-Process -Id $taskSelected.ProcessId -ErrorAction SilentlyContinue
        if(-not $taskProcess -or [Math]::Abs(($taskProcess.StartTime-$taskSelected.CreationDate).TotalMilliseconds) -gt 1){break}
        try{$taskModules=@($taskProcess.Modules | Where-Object {$_.ModuleName -match '^(dinput8|dbghelp|XFE.*)\.dll$'} | ForEach-Object {[ordered]@{name=$_.ModuleName;file=$_.FileName}})}catch{$taskModules=@()}
        $taskSamples.Add([ordered]@{time=[DateTimeOffset]::Now;workingSet=$taskProcess.WorkingSet64;modules=$taskModules})
        Start-Sleep -Seconds 2
    }
    $taskProcess=Get-Process -Id $taskSelected.ProcessId -ErrorAction SilentlyContinue
    $taskSurvived=($null -ne $taskProcess -and [Math]::Abs(($taskProcess.StartTime-$taskSelected.CreationDate).TotalMilliseconds) -le 1 -and (Get-Date) -ge $taskDeadline)
}
$taskReport=[ordered]@{label=$Label;startedAt=$taskBegin;completedAt=Get-Date;processId=$taskSelected.ProcessId;secondsRequested=$Seconds;survived=$taskSurvived;files=$taskFiles;samples=$taskSamples;gameInputsSent=0;screenUse=$false}
$taskReport | ConvertTo-Json -Depth 8 | Set-Content -LiteralPath $taskOutput -Encoding utf8
[ordered]@{label=$Label;processId=$taskSelected.ProcessId;survived=$taskSurvived;samples=$taskSamples.Count;report=$taskOutput} | ConvertTo-Json