Re-use the singlefilehost instead of using a fresh one to reduce package size

This commit is contained in:
Caelan Sayler
2022-05-22 15:03:58 +01:00
parent 6fa23e2c21
commit 2a4e897f6b
5 changed files with 39 additions and 20 deletions

View File

@@ -38,7 +38,6 @@ Copy-Item "$In\Win32\Setup.exe" -Destination "$BinOut"
Copy-Item "$In\Win32\StubExecutable.exe" -Destination "$BinOut" Copy-Item "$In\Win32\StubExecutable.exe" -Destination "$BinOut"
Copy-Item "$PSScriptRoot\vendor\rcedit.exe" -Destination "$BinOut" Copy-Item "$PSScriptRoot\vendor\rcedit.exe" -Destination "$BinOut"
Copy-Item "$PSScriptRoot\vendor\signtool.exe" -Destination "$BinOut" Copy-Item "$PSScriptRoot\vendor\signtool.exe" -Destination "$BinOut"
Copy-Item "$PSScriptRoot\vendor\singlefilehost.exe" -Destination "$BinOut"
Copy-Item -Path "$PSScriptRoot\vendor\7za.exe" -Destination "$BinOut" Copy-Item -Path "$PSScriptRoot\vendor\7za.exe" -Destination "$BinOut"
# Clean up files we do not need to create a nuget package # Clean up files we do not need to create a nuget package

View File

@@ -119,26 +119,20 @@ namespace Squirrel.CommandLine
{ {
using var _ = Utility.GetTempDirectory(out var tmpdir); using var _ = Utility.GetTempDirectory(out var tmpdir);
var sourceName = Path.GetFileNameWithoutExtension(sourceFile); var sourceName = Path.GetFileNameWithoutExtension(sourceFile);
var newAppHost = Path.Combine(tmpdir, sourceName + ".exe");
// extract Update.exe to tmp dir // extract bundled Update.exe assets to tmp dir
Log.Info("Extracting Update.exe resources to temp directory"); Log.Info("Extracting Update.exe resources");
File.Copy(sourceFile, newAppHost);
DumpPackageAssemblies(sourceFile, tmpdir); DumpPackageAssemblies(sourceFile, tmpdir);
// create new app host // set new icon (which eradicates bundled assets)
var newAppHost = Path.Combine(tmpdir, sourceName + ".exe");
HostWriter.CreateAppHost(
HelperExe.SingleFileHostPath, // input file
newAppHost, // output file
sourceName + ".dll", // entry point, relative to apphost
true, // isGui?
Path.Combine(tmpdir, sourceName + ".dll") // copy exe resources from?
);
// set new icon
Log.Info("Patching Update.exe icon"); Log.Info("Patching Update.exe icon");
HelperExe.SetExeIcon(newAppHost, iconPath); HelperExe.SetExeIcon(newAppHost, iconPath);
HostWriter.ResetBundle(newAppHost);
// create new bundle // re-append bundled assets to exe
Log.Info("Re-packing Update.exe bundle");
var bundlerOutput = Path.Combine(tmpdir, "output"); var bundlerOutput = Path.Combine(tmpdir, "output");
Directory.CreateDirectory(bundlerOutput); Directory.CreateDirectory(bundlerOutput);
var bundler = new Bundler( var bundler = new Bundler(
@@ -151,8 +145,6 @@ namespace Squirrel.CommandLine
false, false,
sourceName sourceName
); );
Log.Info("Re-packing Update.exe bundle");
var singleFile = GenerateBundle(bundler, tmpdir, bundlerOutput); var singleFile = GenerateBundle(bundler, tmpdir, bundlerOutput);
// copy to requested location // copy to requested location
@@ -167,7 +159,7 @@ namespace Squirrel.CommandLine
using (var memoryMappedPackage = MemoryMappedFile.CreateFromFile(packageFileName, FileMode.Open, null, 0, MemoryMappedFileAccess.Read)) { using (var memoryMappedPackage = MemoryMappedFile.CreateFromFile(packageFileName, FileMode.Open, null, 0, MemoryMappedFileAccess.Read)) {
using (var packageView = memoryMappedPackage.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read)) { using (var packageView = memoryMappedPackage.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read)) {
var manifest = DotnetUtil.ReadManifest(packageView, bundleHeaderOffset); var manifest = ReadManifest(packageView, bundleHeaderOffset);
foreach (var entry in manifest.Entries) { foreach (var entry in manifest.Entries) {
Stream contents; Stream contents;

View File

@@ -18,7 +18,6 @@ namespace Squirrel.CommandLine
public static string UpdatePath public static string UpdatePath
=> FindHelperFile("Update.exe", p => Microsoft.NET.HostModel.AppHost.HostWriter.IsBundle(p, out var _)); => FindHelperFile("Update.exe", p => Microsoft.NET.HostModel.AppHost.HostWriter.IsBundle(p, out var _));
public static string StubExecutablePath => FindHelperFile("StubExecutable.exe"); public static string StubExecutablePath => FindHelperFile("StubExecutable.exe");
public static string SingleFileHostPath => FindHelperFile("singlefilehost.exe");
// private so we don't expose paths to internal tools. these should be exposed as a helper function // private so we don't expose paths to internal tools. these should be exposed as a helper function
private static string SignToolPath => FindHelperFile("signtool.exe"); private static string SignToolPath => FindHelperFile("signtool.exe");

View File

@@ -209,8 +209,37 @@ namespace Microsoft.NET.HostModel.AppHost
/// Check if the an AppHost is a single-file bundle /// Check if the an AppHost is a single-file bundle
/// </summary> /// </summary>
/// <param name="appHostFilePath">The path of Apphost to check</param> /// <param name="appHostFilePath">The path of Apphost to check</param>
/// <param name="bundleHeaderOffset">An out parameter containing the offset of the bundle header (if any)</param>
/// <returns>True if the AppHost is a single-file bundle, false otherwise</returns> /// <returns>True if the AppHost is a single-file bundle, false otherwise</returns>
public static void ResetBundle(string appHostFilePath)
{
byte[] bundleSignature = {
// 32 bytes represent the bundle signature: SHA-256 for ".net core bundle"
0x8b, 0x12, 0x02, 0xb9, 0x6a, 0x61, 0x20, 0x38,
0x72, 0x7b, 0x93, 0x02, 0x14, 0xd7, 0xa0, 0x32,
0x13, 0xf5, 0xb9, 0xe6, 0xef, 0xae, 0x33, 0x18,
0xee, 0x3b, 0x2d, 0xce, 0x24, 0xb3, 0x6a, 0xae
};
void ResetBundleHeader()
{
using (var memoryMappedFile = MemoryMappedFile.CreateFromFile(appHostFilePath))
{
using (MemoryMappedViewAccessor accessor = memoryMappedFile.CreateViewAccessor())
{
int position = BinaryUtils.SearchInFile(accessor, bundleSignature);
if (position == -1)
{
throw new PlaceHolderNotFoundInAppHostException(bundleSignature);
}
accessor.WriteArray(position - sizeof(long), new byte[sizeof(long)], 0, sizeof(long));
}
}
}
RetryUtil.RetryOnIOError(ResetBundleHeader);
}
public static bool IsBundle(string appHostFilePath, out long bundleHeaderOffset) public static bool IsBundle(string appHostFilePath, out long bundleHeaderOffset)
{ {
byte[] bundleSignature = { byte[] bundleSignature = {

Binary file not shown.