param( [Parameter(Mandatory = $true)] [string]$Executable, [Parameter(Mandatory = $false)] [string]$Output = "artifacts" ) $ErrorActionPreference = "Stop" if (-not (Test-Path $Executable)) { throw "Executable does not exist: $Executable" } New-Item -ItemType Directory -Force -Path $Output | Out-Null $vswherePath = "${env:ProgramFiles(x86)}\Microsoft Visual Studio\Installer\vswhere.exe" if (-not (Test-Path $vswherePath)) { throw "Could not locate vswhere.exe. Verify that Visual Studio or Visual Studio Build Tools is installed." } $visualStudioPath = & $vswherePath ` -latest ` -products * ` -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 ` -property installationPath if (-not $visualStudioPath) { throw "Could not locate a Visual Studio installation with the MSVC C++ tools installed." } $toolsetVersionPath = Join-Path ` $visualStudioPath ` "VC\Auxiliary\Build\Microsoft.VCToolsVersion.default.txt" if (-not (Test-Path $toolsetVersionPath)) { throw "Could not locate the MSVC toolset version file." } $toolsetVersion = (Get-Content $toolsetVersionPath -Raw).Trim() $dumpbinPath = Join-Path ` $visualStudioPath ` "VC\Tools\MSVC\$toolsetVersion\bin\Hostx64\x64\dumpbin.exe" if (-not (Test-Path $dumpbinPath)) { throw "Could not locate dumpbin.exe at: $dumpbinPath" } Write-Host "Using dumpbin: $dumpbinPath" $windowsDirectories = @( $env:WINDIR, (Join-Path $env:WINDIR "System32"), (Join-Path $env:WINDIR "SysWOW64") ) $processed = @{} function Test-IsWindowsSystemDll { param( [string]$Name ) foreach ($directory in $windowsDirectories) { $path = Join-Path $directory $Name if (Test-Path $path) { return $true } } return $false } function Find-Dependency { param( [string]$Name, [string]$BinaryDirectory ) $localPath = Join-Path $BinaryDirectory $Name if (Test-Path $localPath) { return $localPath } $command = Get-Command $Name -ErrorAction SilentlyContinue if ($command) { return $command.Source } return $null } function Copy-Dependencies { param( [string]$Binary ) $binaryDirectory = Split-Path -Parent $Binary $dependencies = & $dumpbinPath /DEPENDENTS $Binary | Select-String '^\s+.*\.dll$' | ForEach-Object { $_.Line.Trim() } | Sort-Object -Unique foreach ($dll in $dependencies) { $key = $dll.ToLowerInvariant() if ($processed.ContainsKey($key)) { continue } $processed[$key] = $true if (Test-IsWindowsSystemDll $dll) { Write-Host "Skipping Windows system dependency: $dll" continue } $source = Find-Dependency ` -Name $dll ` -BinaryDirectory $binaryDirectory if (-not $source) { Write-Warning "Could not locate dependency: $dll" continue } $destination = Join-Path $Output (Split-Path -Leaf $source) if (-not (Test-Path $destination)) { Write-Host "Copying dependency: $source" Copy-Item $source $destination -Force } Copy-Dependencies -Binary $source } } Copy-Dependencies -Binary $Executable