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 "$PSScriptRoot\vendor\rcedit.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"
# 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);
var sourceName = Path.GetFileNameWithoutExtension(sourceFile);
var newAppHost = Path.Combine(tmpdir, sourceName + ".exe");
// extract Update.exe to tmp dir
Log.Info("Extracting Update.exe resources to temp directory");
// extract bundled Update.exe assets to tmp dir
Log.Info("Extracting Update.exe resources");
File.Copy(sourceFile, newAppHost);
DumpPackageAssemblies(sourceFile, tmpdir);
// create new app host
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
// set new icon (which eradicates bundled assets)
Log.Info("Patching Update.exe icon");
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");
Directory.CreateDirectory(bundlerOutput);
var bundler = new Bundler(
@@ -151,8 +145,6 @@ namespace Squirrel.CommandLine
false,
sourceName
);
Log.Info("Re-packing Update.exe bundle");
var singleFile = GenerateBundle(bundler, tmpdir, bundlerOutput);
// 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 packageView = memoryMappedPackage.CreateViewAccessor(0, 0, MemoryMappedFileAccess.Read)) {
var manifest = DotnetUtil.ReadManifest(packageView, bundleHeaderOffset);
var manifest = ReadManifest(packageView, bundleHeaderOffset);
foreach (var entry in manifest.Entries) {
Stream contents;

View File

@@ -18,7 +18,6 @@ namespace Squirrel.CommandLine
public static string UpdatePath
=> FindHelperFile("Update.exe", p => Microsoft.NET.HostModel.AppHost.HostWriter.IsBundle(p, out var _));
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 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
/// </summary>
/// <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>
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)
{
byte[] bundleSignature = {

Binary file not shown.