66 [string ]$OutputDirectory = " $env: TEMP " ,
77
88 [Parameter (Mandatory = $false )]
9- [switch ]$UseCPUProfile = $true
9+ [switch ]$UseCPUProfile = $true ,
10+
11+ [Parameter (Mandatory = $false )]
12+ [string ]$ExeName = " " ,
13+
14+ [Parameter (Mandatory = $false )]
15+ [string ]$UserDataDir = " "
1016)
1117
1218# Load Windows Forms assembly for GUI
@@ -298,7 +304,8 @@ function Create-DiagnosticZip {
298304 [string ]$RegistryFilePath ,
299305 [string ]$DirectoryFilePath ,
300306 [string ]$TraceFilePath ,
301- [string ]$ZipPath
307+ [string ]$ZipPath ,
308+ [string ]$CrashpadFolderPath = " "
302309 )
303310
304311 try {
@@ -369,6 +376,42 @@ function Create-DiagnosticZip {
369376 }
370377 }
371378
379+ # Add Crashpad folder if it exists
380+ if ($CrashpadFolderPath -and (Test-Path $CrashpadFolderPath )) {
381+ try {
382+ Write-Host " Adding Crashpad folder contents..." - ForegroundColor Cyan
383+ $crashpadFiles = Get-ChildItem - Path $CrashpadFolderPath - Recurse - File - ErrorAction SilentlyContinue
384+
385+ # Trim trailing backslash to ensure correct substring calculation
386+ $crashpadBasePath = $CrashpadFolderPath.TrimEnd (' \' )
387+
388+ foreach ($crashpadFile in $crashpadFiles ) {
389+ try {
390+ # Get relative path within Crashpad folder
391+ $relativePath = $crashpadFile.FullName.Substring ($crashpadBasePath.Length + 1 )
392+ $zipEntryName = " Crashpad/$relativePath " .Replace(" \" , " /" )
393+
394+ $entry = $zip.CreateEntry ($zipEntryName )
395+ $entryStream = $entry.Open ()
396+
397+ $fileStream = [System.IO.File ]::Open($crashpadFile.FullName , [System.IO.FileMode ]::Open, [System.IO.FileAccess ]::Read, [System.IO.FileShare ]::ReadWrite)
398+ $fileStream.CopyTo ($entryStream )
399+ $fileStream.Close ()
400+ $entryStream.Close ()
401+
402+ $fileSize = $crashpadFile.Length / 1 KB
403+ Write-Host " Added to zip: Crashpad/$relativePath ($ ( [math ]::Round($fileSize , 2 )) KB)" - ForegroundColor Cyan
404+ }
405+ catch {
406+ Write-Host " Failed to add $ ( $crashpadFile.Name ) : $ ( $_.Exception.Message ) " - ForegroundColor Red
407+ }
408+ }
409+ }
410+ catch {
411+ Write-Host " Failed to add Crashpad folder: $ ( $_.Exception.Message ) " - ForegroundColor Red
412+ }
413+ }
414+
372415 $zip.Dispose ()
373416
374417 # Calculate final zip size
@@ -434,7 +477,7 @@ function Stop-WPRTrace {
434477 # Create diagnostic zip with all collected files
435478 Write-Host " "
436479 Write-Host " Creating diagnostic package..." - ForegroundColor Cyan
437- $zipResult = Create- DiagnosticZip - RegistryFilePath $script :RegistryFilePath - DirectoryFilePath $script :DirectoryFilePath - TraceFilePath $TracePath - ZipPath $script :FinalZipPath
480+ $zipResult = Create- DiagnosticZip - RegistryFilePath $script :RegistryFilePath - DirectoryFilePath $script :DirectoryFilePath - TraceFilePath $TracePath - ZipPath $script :FinalZipPath - CrashpadFolderPath $ script :CrashpadFolderPath
438481
439482 if ($zipResult ) {
440483 Write-Host " All diagnostic files have been packaged and saved to: $zipResult " - ForegroundColor Green
@@ -700,6 +743,100 @@ function Export-EdgeUpdateRegistry {
700743 }
701744}
702745
746+ # Function to get user data folders from WebView2 processes
747+ function Get-WebView2UserDataFolder {
748+ param (
749+ [Parameter (Mandatory = $false )]
750+ [string ]$ExeName ,
751+
752+ [Parameter (Mandatory = $false )]
753+ [string ]$UserDataDir = " "
754+ )
755+
756+ try {
757+ # Look for Crashpad folder
758+ $crashpadFolder = " "
759+ $folderToCheck = " "
760+ $foundUserDataFolder = " "
761+
762+ if (-not [string ]::IsNullOrWhiteSpace($UserDataDir )) {
763+ # Validate UserDataDir to prevent path traversal
764+ if ($UserDataDir -match ' \.\.' ) {
765+ Write-Host " Error: UserDataDir contains path traversal sequences (..). This is not allowed for security reasons." - ForegroundColor Red
766+ return @ { UserDataFolders = @ (); CrashpadFolder = " " }
767+ }
768+
769+ # Check if path is absolute (Windows path or UNC path)
770+ if (-not ([System.IO.Path ]::IsPathRooted($UserDataDir ))) {
771+ Write-Host " Error: UserDataDir must be an absolute path. Relative paths are not allowed." - ForegroundColor Red
772+ return @ { UserDataFolders = @ (); CrashpadFolder = " " }
773+ }
774+
775+ Write-Host " Using provided UserDataDir: $UserDataDir " - ForegroundColor Cyan
776+ $folderToCheck = $UserDataDir
777+ }
778+ elseif (-not [string ]::IsNullOrWhiteSpace($ExeName )) {
779+ Write-Host " Searching for msedgewebview2.exe processes with exe name: $ExeName " - ForegroundColor Green
780+
781+ # Get all msedgewebview2.exe processes with their command lines
782+ $processes = Get-CimInstance Win32_Process - Filter " Name = 'msedgewebview2.exe'" - ErrorAction SilentlyContinue
783+
784+ if (-not $processes ) {
785+ Write-Host " No msedgewebview2.exe processes found" - ForegroundColor Yellow
786+ return @ { UserDataFolders = @ (); CrashpadFolder = " " }
787+ }
788+
789+ foreach ($process in $processes ) {
790+ $commandLine = $process.CommandLine
791+
792+ if ($commandLine ) {
793+ # Check if command line contains required parameters
794+ if ($commandLine -match ' --embedded-browser-webview=1' -and
795+ $commandLine -match " --webview-exe-name=$ ( [regex ]::Escape($ExeName )) " ) {
796+
797+ Write-Host " Process ID $ ( $process.ProcessId ) matches criteria" - ForegroundColor Cyan
798+
799+ # Extract --user-data-dir value
800+ # Pattern handles: --user-data-dir="path" or --user-data-dir=path
801+ if ($commandLine -match ' --user-data-dir=(?:"([^"]+)"|([^\s]+))' ) {
802+ $folderToCheck = if ($matches [1 ]) { $matches [1 ] } else { $matches [2 ] }
803+ $foundUserDataFolder = $folderToCheck
804+ Write-Host " Found user data folder: $folderToCheck " - ForegroundColor Green
805+ break
806+ }
807+ }
808+ }
809+ }
810+
811+ if (-not $folderToCheck ) {
812+ Write-Host " No matching processes found with the specified criteria" - ForegroundColor Yellow
813+ }
814+ }
815+
816+ if (-not [string ]::IsNullOrWhiteSpace($folderToCheck )) {
817+ $crashpadFolder = Join-Path $folderToCheck " Crashpad"
818+
819+ if (Test-Path $crashpadFolder ) {
820+ Write-Host " Checking Crashpad folder: $crashpadFolder " - ForegroundColor Cyan
821+ Write-Host " Found Crashpad folder: $crashpadFolder " - ForegroundColor Green
822+ }
823+ else {
824+ Write-Host " Crashpad folder not found: $crashpadFolder " - ForegroundColor Yellow
825+ $crashpadFolder = " "
826+ }
827+ }
828+ else {
829+ Write-Host " No user data folder available to check for Crashpad" - ForegroundColor Yellow
830+ }
831+
832+ return @ { UserDataFolders = @ ($foundUserDataFolder ); CrashpadFolder = $crashpadFolder }
833+ }
834+ catch {
835+ Write-Host " Error getting WebView2 user data folders: $ ( $_.Exception.Message ) " - ForegroundColor Red
836+ return @ { UserDataFolders = @ (); CrashpadFolder = " " }
837+ }
838+ }
839+
703840# Collect installer logs.
704841$registryResult = Export-EdgeUpdateRegistry - OutputDirectory $OutputDirectory
705842Write-Host " "
@@ -721,5 +858,23 @@ Write-Host "Directory file: $directoryResult" -ForegroundColor Yellow
721858Write-Host " Zip destination: $ZipPath " - ForegroundColor Yellow
722859Write-Host " "
723860
861+ $result = @ { UserDataFolders = @ (); CrashpadFolder = " " }
862+ if (-not [string ]::IsNullOrWhiteSpace($ExeName ) -or -not [string ]::IsNullOrWhiteSpace($UserDataDir )) {
863+ $result = Get-WebView2UserDataFolder - ExeName $ExeName - UserDataDir $UserDataDir
864+ Write-Host " User data folders found: $ ( $result.UserDataFolders.Count ) " - ForegroundColor Yellow
865+ foreach ($folder in $result.UserDataFolders ) {
866+ Write-Host " $folder " - ForegroundColor Yellow
867+ }
868+ Write-Host " "
869+ }
870+ else {
871+ Write-Host " ExeName and UserDataDir not provided, skipping user data folder detection" - ForegroundColor Yellow
872+ Write-Host " "
873+ }
874+
875+ # Set Crashpad folder path
876+ $script :CrashpadFolderPath = $result.CrashpadFolder
877+ Write-Host " "
878+
724879# Start WPR tracing automatically
725880StartWPR - OutputDirectory $OutputDirectory - OutPath $OutPath - UseCPUProfile $UseCPUProfile
0 commit comments