Prevent building packages for non-aware apps

This commit is contained in:
Caelan Sayler
2023-12-31 21:52:34 +00:00
parent 1b66d3efbe
commit caf1e688b6
8 changed files with 129 additions and 21 deletions

View File

@@ -20,6 +20,11 @@ name = "testapp"
path = "src/testapp.rs"
required-features = ["windows"]
[[bin]]
name = "testawareapp"
path = "src/testawareapp.rs"
required-features = ["windows"]
[[bin]]
name = "stub"
path = "src/stub.rs"

View File

@@ -3,14 +3,8 @@ use std::{fs::OpenOptions, io::Write};
fn main() -> Result<()> {
let args: Vec<String> = std::env::args().skip(1).collect();
// Join the arguments with a space
let line = args.join(" ") + "\n";
// Open "args.txt" for appending
let mut file = OpenOptions::new().create(true).append(true).open("args.txt")?;
// Write the line to the file
file.write_all(line.as_bytes())?;
Ok(())
}

View File

@@ -0,0 +1,16 @@
use anyhow::Result;
use std::{fs::OpenOptions, io::Write};
fn main() -> Result<()> {
let args: Vec<String> = std::env::args().skip(1).collect();
if args[0] == "--veloapp-version" {
println!("1.0.0");
return Ok(());
}
let line = args.join(" ") + "\n";
let mut file = OpenOptions::new().create(true).append(true).open("args.txt")?;
file.write_all(line.as_bytes())?;
Ok(())
}

View File

@@ -1,5 +1,7 @@
using System.Text;
using System.Diagnostics;
using System.Text;
using Microsoft.Extensions.Logging;
using NuGet.Versioning;
using Velopack.NuGet;
using Velopack.Windows;
@@ -85,6 +87,22 @@ public class WindowsReleasifyCommandRunner
if (!File.Exists(mainExe))
throw new ArgumentException($"--exeName '{options.EntryExecutableName}' does not exist in package. Searched at: '{mainExe}'");
try {
var psi = new ProcessStartInfo(mainExe);
psi.AppendArgumentListSafe(new[] { "--veloapp-version" }, out var _);
var output = psi.Output(5000);
if (String.IsNullOrWhiteSpace(output)) {
throw new Exception("Process exited with no output.");
}
var version = SemanticVersion.Parse(output.Trim());
if (version != VelopackRuntimeInfo.VelopackNugetVersion) {
_logger.Warn($"VelopackApp version '{version}' does not match CLI version '{VelopackRuntimeInfo.VelopackNugetVersion}'.");
}
} catch {
_logger.Error("Failed to verify VelopackApp. Ensure you have added the startup code to your Program.Main(): VelopackApp.Build().Run();");
throw;
}
var spec = NuspecManifest.ParseFromFile(nuspecPath);
// warning if there are long paths (>200 char) in this package. 260 is max path

View File

@@ -119,6 +119,9 @@ namespace Velopack.Compression
p.Kill();
throw new TimeoutException("zstd patch process timed out (60s).");
}
if (p.ExitCode != 0) {
throw new Exception($"zstd patch process failed with exit code {p.ExitCode}.");
}
verifyPatchedFile(relativeFilePath, inputFile, tempTargetFile);
} else if (relativeFilePath.EndsWith(".bsdiff", StringComparison.InvariantCultureIgnoreCase)) {
using (var of = File.OpenWrite(tempTargetFile))

View File

@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
@@ -57,6 +58,41 @@ namespace Velopack
return p;
}
public static string Output(this ProcessStartInfo psi, int timeoutMs)
{
psi.RedirectStandardOutput = true;
psi.RedirectStandardError = true;
psi.UseShellExecute = false;
var p = Process.Start(psi);
p.BeginErrorReadLine();
p.BeginOutputReadLine();
var sb = new StringBuilder();
p.ErrorDataReceived += (o, e) => {
if (e.Data != null) {
sb.AppendLine(e.Data);
}
};
p.OutputDataReceived += (o, e) => {
if (e.Data != null) {
sb.AppendLine(e.Data);
}
};
if (!p.WaitForExit(timeoutMs)) {
throw new TimeoutException($"Process timed out after {timeoutMs}ms.");
}
if (p.ExitCode != 0) {
throw new Exception($"Process exited with code {p.ExitCode}.");
}
return sb.ToString();
}
// https://source.dot.net/#System.Diagnostics.Process/System/Diagnostics/ProcessStartInfo.cs,204
private static void AppendArgumentsTo(StringBuilder stringBuilder, IEnumerable<string> args)

View File

@@ -149,8 +149,6 @@ namespace Velopack
public void Run(ILogger logger = null)
{
var args = _args ?? Environment.GetCommandLineArgs().Skip(1).ToArray();
var log = logger ?? NullLogger.Instance;
var locator = _locator ?? VelopackLocator.GetDefault(log);
// internal hook run by the Velopack tooling to check everything is working
if (args.Length >= 1 && args[0].Equals("--veloapp-version", StringComparison.OrdinalIgnoreCase)) {
@@ -159,6 +157,9 @@ namespace Velopack
return;
}
var log = logger ?? NullLogger.Instance;
var locator = _locator ?? VelopackLocator.GetDefault(log);
log.Info("Starting Velopack App (Run).");
// first, we run any fast exit hooks

View File

@@ -38,12 +38,13 @@ public class WindowsPackTests
using var _2 = Utility.GetTempDirectory(out var tmpReleaseDir);
using var _3 = Utility.GetTempDirectory(out var unzipDir);
var exe = "testapp.exe";
var exe = "testawareapp.exe";
var pdb = Path.ChangeExtension(exe, ".pdb");
var id = "Test.Squirrel-App";
var version = "1.0.0";
File.Copy(HelperFile.FindTestFile(exe), Path.Combine(tmpOutput, exe));
File.Copy(HelperFile.FindTestFile("testapp.pdb"), Path.Combine(tmpOutput, "testapp.pdb"));
File.Copy(HelperFile.FindTestFile(pdb), Path.Combine(tmpOutput, pdb));
var options = new WindowsPackOptions {
EntryExecutableName = exe,
@@ -88,8 +89,8 @@ public class WindowsPackTests
Assert.Equal("10.0.19043", xml.Root.ElementsNoNamespace("metadata").Single().ElementsNoNamespace("osMinVersion").Single().Value);
// check for other files
Assert.True(File.Exists(Path.Combine(unzipDir, "lib", "app", "testapp.exe")));
Assert.True(File.Exists(Path.Combine(unzipDir, "lib", "app", "testapp.pdb")));
Assert.True(File.Exists(Path.Combine(unzipDir, "lib", "app", Path.GetFileName(exe))));
Assert.True(File.Exists(Path.Combine(unzipDir, "lib", "app", Path.GetFileName(pdb))));
}
[SkippableFact]
@@ -102,12 +103,13 @@ public class WindowsPackTests
using var _1 = Utility.GetTempDirectory(out var tmpOutput);
using var _2 = Utility.GetTempDirectory(out var tmpReleaseDir);
var exe = "testapp.exe";
var exe = "testawareapp.exe";
var pdb = Path.ChangeExtension(exe, ".pdb");
var id = "Test.Squirrel-App";
var version = "1.0.0";
File.Copy(HelperFile.FindTestFile(exe), Path.Combine(tmpOutput, exe));
File.Copy(HelperFile.FindTestFile("testapp.pdb"), Path.Combine(tmpOutput, "testapp.pdb"));
File.Copy(HelperFile.FindTestFile(pdb), Path.Combine(tmpOutput, pdb));
var options = new WindowsPackOptions {
EntryExecutableName = exe,
@@ -167,12 +169,13 @@ public class WindowsPackTests
using var _1 = Utility.GetTempDirectory(out var tmpOutput);
using var _2 = Utility.GetTempDirectory(out var tmpReleaseDir);
var exe = "testapp.exe";
var exe = "testawareapp.exe";
var pdb = Path.ChangeExtension(exe, ".pdb");
var id = "Test.Squirrel-App";
var version = "1.0.0";
File.Copy(HelperFile.FindTestFile(exe), Path.Combine(tmpOutput, exe));
File.Copy(HelperFile.FindTestFile("testapp.pdb"), Path.Combine(tmpOutput, "testapp.pdb"));
File.Copy(HelperFile.FindTestFile(pdb), Path.Combine(tmpOutput, pdb));
var options = new WindowsPackOptions {
EntryExecutableName = exe,
@@ -195,6 +198,37 @@ public class WindowsPackTests
Assert.Throws<ArgumentException>(() => runner.Pack(options));
}
[SkippableFact]
public void PackRefuseBuildingUnawareApp()
{
Skip.IfNot(VelopackRuntimeInfo.IsWindows);
using var logger = _output.BuildLoggerFor<WindowsPackTests>();
using var _1 = Utility.GetTempDirectory(out var tmpOutput);
using var _2 = Utility.GetTempDirectory(out var tmpReleaseDir);
var exe = "testapp.exe";
var pdb = Path.ChangeExtension(exe, ".pdb");
var id = "Test.Squirrel-App";
var version = "1.0.0";
File.Copy(HelperFile.FindTestFile(exe), Path.Combine(tmpOutput, exe));
File.Copy(HelperFile.FindTestFile(pdb), Path.Combine(tmpOutput, pdb));
var options = new WindowsPackOptions {
EntryExecutableName = exe,
ReleaseDir = new DirectoryInfo(tmpReleaseDir),
PackId = id,
PackVersion = version,
TargetRuntime = RID.Parse("win"),
PackDirectory = tmpOutput,
};
var runner = new WindowsPackCommandRunner(logger);
Assert.Throws<Exception>(() => runner.Pack(options));
}
[SkippableFact]
public void PackBuildsPackageWhichIsInstallable()
{
@@ -206,12 +240,13 @@ public class WindowsPackTests
using var _2 = Utility.GetTempDirectory(out var tmpReleaseDir);
using var _3 = Utility.GetTempDirectory(out var tmpInstallDir);
var exe = "testapp.exe";
var exe = "testawareapp.exe";
var pdb = Path.ChangeExtension(exe, ".pdb");
var id = "Test.Squirrel-App";
var version = "1.0.0";
File.Copy(HelperFile.FindTestFile(exe), Path.Combine(tmpOutput, exe));
File.Copy(HelperFile.FindTestFile("testapp.pdb"), Path.Combine(tmpOutput, "testapp.pdb"));
File.Copy(HelperFile.FindTestFile(pdb), Path.Combine(tmpOutput, pdb));
var options = new WindowsPackOptions {
EntryExecutableName = exe,
@@ -233,7 +268,7 @@ public class WindowsPackTests
var updatePath = Path.Combine(tmpInstallDir, "Update.exe");
Assert.True(File.Exists(updatePath));
var appPath = Path.Combine(tmpInstallDir, "current", "testapp.exe");
var appPath = Path.Combine(tmpInstallDir, "current", "testawareapp.exe");
Assert.True(File.Exists(appPath));
var argsPath = Path.Combine(tmpInstallDir, "current", "args.txt");