180 lines
6.3 KiB
PowerShell
180 lines
6.3 KiB
PowerShell
|
function Find-MissingReferences {
|
||
|
<#
|
||
|
.SYNOPSIS
|
||
|
Used to fetch all the assembly references and find which ones are missing from the folder presented by Path
|
||
|
|
||
|
.DESCRIPTION
|
||
|
Will check for files that should be present in the folder but which are not. Will assume any file loaded from the GAC is acceptable to not be present in the folder.
|
||
|
|
||
|
.PARAMETER Path
|
||
|
The folder where we should look for the files, or the full path of the file to be checked
|
||
|
|
||
|
.PARAMETER EntryPoint
|
||
|
Specify a specific file to consider the entry point for determining what is missing.
|
||
|
|
||
|
.PARAMETER ThrowOnError
|
||
|
Use this in a build environment if required
|
||
|
|
||
|
.PARAMETER Noisy
|
||
|
Be noisy. Show me all the stuff with warnings and such.
|
||
|
|
||
|
.PARAMETER Recursing
|
||
|
Don't set this
|
||
|
#>
|
||
|
[CmdletBinding()]
|
||
|
[OutputType([string[]])]
|
||
|
param (
|
||
|
[Parameter(Mandatory = $true)]
|
||
|
[string]$Path,
|
||
|
[Parameter(Mandatory = $false)]
|
||
|
[string]$EntryPoint,
|
||
|
[switch]$ThrowOnError,
|
||
|
[switch]$Noisy,
|
||
|
[switch]$Recursing
|
||
|
)
|
||
|
|
||
|
$logLead = Get-LogLeadName
|
||
|
|
||
|
if ($null -eq $global:allReferencedAssemblies) {
|
||
|
# You weren't supposed to set this, so if this value doesn't exist, then we can't be here
|
||
|
# Set the value to false so we can check it later for writing data out
|
||
|
$Recursing = $false
|
||
|
$global:allReferencedAssemblies = @()
|
||
|
}
|
||
|
if ($null -eq $global:loadedReferencesAlready) {
|
||
|
$global:loadedReferencesAlready = @()
|
||
|
}
|
||
|
if ($null -eq $global:missingReferences) {
|
||
|
$global:missingReferences = @()
|
||
|
}
|
||
|
|
||
|
# early exit if we already encountered this before
|
||
|
if ($global:missingReferences -contains $EntryPoint) {
|
||
|
return
|
||
|
}
|
||
|
if ($global:loadedReferencesAlready -contains $EntryPoint) {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
# Check to see if it is in the GAC
|
||
|
try {
|
||
|
$assembly = [System.Reflection.Assembly]::Load($reference)
|
||
|
if ($null -ne $assembly) {
|
||
|
if ($Noisy) {
|
||
|
Write-Host "$($assembly.GetName().Name) - GAC? $($assembly.GlobalAssemblyCache) - $($assembly.Location)"
|
||
|
}
|
||
|
}
|
||
|
$global:loadedReferencesAlready += $assembly.GetName().Name
|
||
|
} catch {
|
||
|
# Keep going
|
||
|
}
|
||
|
|
||
|
|
||
|
if (!(Test-Path -Path $Path)) {
|
||
|
throw "$logLead : The path provided is not a valid path or does not exist."
|
||
|
}
|
||
|
|
||
|
$Path = Resolve-Path $Path
|
||
|
|
||
|
$item = Get-Item -Path $Path
|
||
|
|
||
|
$files = @()
|
||
|
|
||
|
if ($item.PSIsContainer) {
|
||
|
if ([string]::IsNullOrWhiteSpace($EntryPoint)) {
|
||
|
if ($Recursing) {
|
||
|
return
|
||
|
}
|
||
|
# We were given a folder, nut no EntryPoint, so just check all the files in the folder
|
||
|
$files = (Get-ChildItem (Join-Path -Path $Path "*.dll") -File).Name
|
||
|
} else {
|
||
|
if (!$EntryPoint.EndsWith(".dll")) {
|
||
|
$entryPointFileName = "$EntryPoint.dll"
|
||
|
}
|
||
|
$filePath = Join-Path -Path $Path -ChildPath $entryPointFileName
|
||
|
if (!(Test-Path $filePath)) {
|
||
|
$global:missingReferences += $EntryPoint
|
||
|
if ($Noisy) {
|
||
|
Write-Warning "$logLead : The file [$entryPointFileName] specified was not found in [$Path]"
|
||
|
}
|
||
|
return
|
||
|
}
|
||
|
$files = (Get-ChildItem $filePath -File).Name
|
||
|
}
|
||
|
} else {
|
||
|
# We were given a file directly
|
||
|
$EntryPoint = $item.Name
|
||
|
$Path = $item.Directory.FullName
|
||
|
$files = @($EntryPoint)
|
||
|
}
|
||
|
|
||
|
foreach ($file in $files) {
|
||
|
$fullName = (Join-Path -Path $Path -ChildPath $file)
|
||
|
$assembly = [System.Reflection.Assembly]::LoadFile($fullName)
|
||
|
$referencedAssemblies = $assembly.GetReferencedAssemblies()
|
||
|
$global:loadedReferencesAlready += $assembly.Name
|
||
|
# [System.IO.Path]::GetFileNameWithoutExtension($fullName)
|
||
|
foreach ($reference in $referencedAssemblies) {
|
||
|
$referenceName = $reference.Name
|
||
|
if ([string]::IsNullOrWhiteSpace($referenceName)) {
|
||
|
continue
|
||
|
}
|
||
|
if ($global:loadedReferencesAlready -contains $referenceName) {
|
||
|
continue
|
||
|
}
|
||
|
if ($global:allReferencedAssemblies -notcontains $referenceName) {
|
||
|
# Write-Host "add ref $referenceName"
|
||
|
$global:allReferencedAssemblies += $referenceName
|
||
|
$discard = Find-MissingReferences -Path $Path -EntryPoint $referenceName -Recursing -Noisy:$Noisy
|
||
|
}
|
||
|
}
|
||
|
$global:loadedReferencesAlready += $assembly.GetName().Name
|
||
|
}
|
||
|
|
||
|
if (!$Recursing) {
|
||
|
# cleanup the "missing" list because of GAC stuff
|
||
|
$missing = @()
|
||
|
foreach ($ref in $global:missingReferences) {
|
||
|
if ($global:loadedReferencesAlready -notcontains $ref) {
|
||
|
$missing += $ref
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if ($Noisy) {
|
||
|
Write-Host "Found these referenced assemblies"
|
||
|
if ($null -ne ${function:Show-ListAsTable}) {
|
||
|
Show-ListAsTable ($global:allReferencedAssemblies | Sort-Object | Get-Unique)
|
||
|
} else {
|
||
|
Write-Host (($global:missingReferences | Sort-Object | Get-Unique) -Join "`n")
|
||
|
}
|
||
|
|
||
|
Write-Host "Found these available assemblies"
|
||
|
if ($null -ne ${function:Show-ListAsTable}) {
|
||
|
Show-ListAsTable ($global:loadedReferencesAlready | Sort-Object | Get-Unique)
|
||
|
} else {
|
||
|
Write-Host (($global:missingReferences | Sort-Object | Get-Unique) -Join "`n")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (!(Test-IsCollectionNullOrEmpty $global:missingReferences)) {
|
||
|
Write-Host "Found these missing references"
|
||
|
if ($null -ne ${function:Show-ListAsTable}) {
|
||
|
Show-ListAsTable ($missing | Sort-Object | Get-Unique)
|
||
|
} else {
|
||
|
Write-Host (($missing | Sort-Object | Get-Unique) -Join "`n")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
Remove-Variable -Name missingReferences -Scope Global
|
||
|
Remove-Variable -Name allReferencedAssemblies -Scope Global
|
||
|
Remove-Variable -Name loadedReferencesAlready -Scope Global
|
||
|
|
||
|
if ($ThrowOnError) {
|
||
|
if (!(Test-IsCollectionNullOrEmpty $missing)) {
|
||
|
throw "$logLead : You're missing some required references"
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return $missing
|
||
|
}
|
||
|
}
|