Skip to content

Instantly share code, notes, and snippets.

@awakecoding
Last active July 22, 2024 15:56
Show Gist options
  • Save awakecoding/c9171965001df09f02f44edec5439ade to your computer and use it in GitHub Desktop.
Save awakecoding/c9171965001df09f02f44edec5439ade to your computer and use it in GitHub Desktop.
ReadyToRun.ps1
# Find crossgen2.exe
$NugetPackagesPath = "$Env:USERPROFILE\.nuget\packages"
$NugetPackageName = "Microsoft.NETCore.App.Crossgen2.win-x64"
$NugetPackageCache = Join-Path $NugetPackagesPath ($NugetPackageName.ToLower())
$CrossGen2Tool = Get-Item "$NugetPackageCache\*\tools\crossgen2.exe" | Sort-Object -Descending | Select-Object -First 1
$CrossGen2Exe = $CrossGen2Tool.FullName
$CrossGen2Dir = $CrossGen2Tool.Directory.FullName
$Env:PATH+=";$CrossGen2Dir" # add crossgen2.exe to PATH
function Get-ReferenceAssemblyPaths
{
param (
[string] $RuntimeConfigPath
)
$DotNetRootShared = "$Env:ProgramFiles\dotnet\shared"
$RuntimeConfig = Get-Content $RuntimeConfigPath -Raw | ConvertFrom-Json
$AssemblyPaths = @([System.IO.Path]::GetDirectoryName($RuntimeConfigPath))
$Runtimeconfig.runtimeOptions.frameworks | ForEach-Object {
$FrameworkName = $_.Name
$Version = [Version] $_.version
$VersionFilter = "$($Version.Major).$($Version.Minor).*"
$FrameworkAssemblyPath = Get-Item "$DotNetRootShared\$FrameworkName\$VersionFilter" | Sort-Object -Descending | Select-Object -First 1
$AssemblyPaths += $FrameworkAssemblyPath.FullName
}
$AssemblyPaths
}
function Get-FullPathOfReferencedAssembly {
param (
[string] $AssemblyName,
[string[]] $ReferenceAssemblyPaths
)
foreach ($ReferenceAssemblyPath in $ReferenceAssemblyPaths) {
$AssemblyPath = Get-ChildItem "$ReferenceAssemblyPath" -Filter "$AssemblyName.dll" -ErrorAction SilentlyContinue | Select-Object -First 1
if ($AssemblyPath) { break }
}
if ($AssemblyPath) {
return $AssemblyPath.FullName
} else {
return ""
}
}
function Get-ReferencedAssemblies
{
param (
[string] $AssemblyPath,
[string] $RuntimeConfigPath,
[switch] $IncludeEverything
)
$ReferenceAssemblyPaths = Get-ReferenceAssemblyPaths -RuntimeConfigPath $RuntimeConfigPath
if ($IncludeEverything) {
$AllDllPaths = $ReferenceAssemblyPaths | ForEach-Object {
Get-ChildItem -Path $_ -Filter "*.dll"
} | Where-Object { $_.FullName -ne $AssemblyPath }
return $AllDllPaths.FullName
}
$assembly = [System.Reflection.Assembly]::LoadFile($AssemblyPath)
$ReferencedAssemblies = $assembly.GetReferencedAssemblies() | ForEach-Object {
try {
$FullPath = Get-FullPathOfReferencedAssembly -AssemblyName $_.Name -ReferenceAssemblyPaths $ReferenceAssemblyPaths
} catch {
$FullPath = ""
}
$FullPath
}
return $ReferencedAssemblies
}
# Change this to the input RDM directory
# Download https://cdn.devolutions.net/download/Devolutions.RemoteDesktopManager.Bin.2024.2.16.0.zip
# then unzip alongside this script before running
$InputDir = "Devolutions.RemoteDesktopManager.Bin.2024.2.16.0"
$OutputDir = $InputDir + "-R2R"
$InputPath = Join-Path $(Get-Location) $InputDir
$OutputPath = Join-Path $(Get-Location) $OutputDir
#Remove-Item -Path $OutputPath -ErrorAction SilentlyContinue -Recurse -Force | Out-Null
#Copy-Item -Path $InputPath -Destination $OutputPath -Recurse
& robocopy.exe $InputPath $OutputPath /E /DCOPY:DA /COPY:DAT /MT:16 /R:3 /W:5 /IS /NFL /NDL /NS /NC /NP
$ReadyToRunInclude = Get-ChildItem -Path "$InputPath/*.dll" -Include 'Devolutions*','RemoteDesktopManager*','DevExpress*' -Exclude *.ni.dll
$RuntimeConfigPath = Join-Path $InputPath "RemoteDesktopManager.runtimeconfig.json"
$ReferenceAssemblyPaths = Get-ReferenceAssemblyPaths -RuntimeConfigPath $RuntimeConfigPath
$SystemReferences = @()
@("System.Private.CoreLib", "System.Runtime", "netstandard", "mscorlib") | ForEach-Object {
$SystemReference = Get-FullPathOfReferencedAssembly -AssemblyName $_ -ReferenceAssemblyPaths $ReferenceAssemblyPaths
$SystemReferences += "-r`:`"$SystemReference`""
}
$TotalSizeDifference = 0
$ReadyToRunInclude | ForEach-Object {
$InputFile = $AssemblyPath = $_.FullName
$OutputFile = Join-Path $OutputDir $_.Name
$ReferencedAssemblies = Get-ReferencedAssemblies -AssemblyPath $AssemblyPath -RuntimeConfigPath $RuntimeConfigPath -IncludeEverything
$References = @()
$References += $SystemReferences
$ReferencedAssemblies | Where-Object { -Not [string]::IsNullOrEmpty($_) }
| Where-Object { Test-Path -Path $_ } | ForEach-Object {
$References += "-r:`"$_`""
}
$CrossGenArgs = @("--targetos:windows", "--targetarch:x64", "-O")
$CrossGenArgs += $References
$CrossGenArgs += "--out:`"$OutputFile`""
$CrossGenArgs += $InputFile
Write-Host "crossgen2.exe $CrossGenArgs"
#Start-Process -FilePath 'crossgen2.exe' -ArgumentList $CrossGenArgs -NoNewWindow -Wait
$ResponseFilePath = [System.IO.Path]::Combine([System.IO.Path]::GetTempPath(), "crossgen2_args.rsp")
$CrossGenArgs | Out-File -FilePath $ResponseFilePath -Encoding Utf8NoBOM
Start-Process -FilePath 'crossgen2.exe' -ArgumentList "@$ResponseFilePath" -NoNewWindow -Wait
Remove-Item $ResponseFilePath
$InputFileSize = (Get-Item $InputFile).Length
$OutputFileSize = (Get-Item $OutputFile).Length
$SizeDifference = $OutputFileSize - $InputFileSize
$SizePercentage = [math]::Round(($SizeDifference / $InputFileSize) * 100, 2)
$TotalSizeDifference += $SizeDifference
Write-Output "$($_.Name)`: $SizePercentage`% larger"
}
$TotalSizeDiffMB = $TotalSizeDifference / 1000 / 1000
Write-Output "ReadyToRun output is $TotalSizeDiffMB MB larger"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment