<# .SYNOPSIS Generate a .lib file for linking to a dll. .DESCRIPTION This script generates a .lib from from a dynamic link library (dll) file. The .lib file can then be linked against to resolve symbols in the dll file. .PARAMETER InputBinary The path to the dll file. .PARAMETER OutPath The output folder in which to save the .lib file. Defaults to the directory of the dll file. The folder must already exist. #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')] param( [Parameter(Mandatory, ValueFromPipeline)] [ValidateScript({($_ -match '\.dll$') -and (Test-Path -Path $_ -PathType Leaf)})] [string]$InputBinary, [Parameter()] [ValidateScript({Test-Path -Path $_ -PathType Container})] [string]$OutPath, [Parameter()] [switch]$Force ) try { $dumpbinBin = (Get-Command -Name 'dumpbin.exe').Source } catch { throw 'Could not find dumpbin.exe in PATH. (Are you running from a Developer Command Prompt?)' } Write-Verbose "Found dumpbin.exe at '$dumpbinBin'" try { $libBin = (Get-Command -Name 'lib.exe').Source } catch { throw 'Could not find lib.exe in PATH. (Are you running from a Developer Command Prompt?)' } Write-Verbose "Found lib.exe at '$libBin'" $inputBinInfo = Get-Item -Path $InputBinary $defTempPath = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath ('{0}.def' -f $inputBinInfo.BaseName) if (-not $OutPath) { $OutPath = $inputBinInfo.DirectoryName } Write-Verbose "Using output path '$OutPath'" $outLibFullName = Join-Path -Path $OutPath -ChildPath ('{0}.lib' -f $inputBinInfo.BaseName) if ((-not (Test-Path -Path $outLibFullName)) -or $PSCmdlet.ShouldProcess($outLibFullName, 'overwrite')) { $archCode = ((. $dumpbinBin /headers $inputBinInfo.FullName | Select-String -Context 1 -SimpleMatch -Pattern 'FILE HEADER VALUES' -CaseSensitive).Context.PostContext | Select-String -Pattern '^\s*([A-Z0-9]+) machine \(.*\)$' -CaseSensitive).Matches[0].Groups[1].Value switch ($archCode) { '14C' { $arch = 'X86' } '8664' { $arch = 'X64' } 'AA64' { $arch = 'ARM64' } default { if ([Environment]::Is64BitOperatingSystem) { $arch = 'X64' } else { $arch = 'X86' } # TODO: Add ARM64 detection fallback Write-Warning "Unable to determine arch of binary. Defaulting to $arch for lib." } } Write-Verbose "Using arch '$arch' for lib generation." $funcs = . $dumpbinBin /exports $inputBinInfo.FullName | Select-String -Pattern '^\s+\d+\s+[A-Z0-9]+\s+[A-Z0-9]+\s+(.+)$' -CaseSensitive | Select-Object -ExpandProperty 'Matches' | ForEach-Object -Process { $_.Groups[1].Value } Write-Verbose "Found $($funcs.Count) functions in '$InputBinary'" Write-Verbose "Creating def file at '$defTempPath'" 'EXPORTS' | Out-File $defTempPath -Force $funcs | Out-File $defTempPath -Append Write-Verbose "Calling lib.exe to generate '$outLibFullName'" . $libBin /def:$defTempPath /OUT:$outLibFullName /MACHINE:$arch Write-Verbose "Removing temp def file at '$defTempPath'" Remove-Item -Path $defTempPath -Confirm:$false }