Fix shortcut hook/updateOnly bug and add test

This commit is contained in:
Caelan Sayler
2024-01-08 14:47:57 +00:00
parent a4ca6d01e7
commit 468d518711
3 changed files with 84 additions and 34 deletions

View File

@@ -51,11 +51,11 @@ namespace Velopack.Windows
/// <summary> Log for diagnostic messages. </summary>
protected ILogger Log { get; }
/// <summary> Locator to use for finding important application paths </summary>
/// <summary> Locator to use for finding important application paths. </summary>
protected IVelopackLocator Locator { get; }
/// <inheritdoc cref="Shortcuts"/>
public Shortcuts(ILogger logger, IVelopackLocator locator)
public Shortcuts(ILogger logger = null, IVelopackLocator locator = null)
{
Log = logger;
Locator = locator;
@@ -70,7 +70,7 @@ namespace Velopack.Windows
CreateShortcut(
Locator.ThisExeRelativePath,
location,
Environment.CommandLine.Contains("squirrel-install") == false,
false,
null, // shortcut arguments
null); // shortcut icon
}
@@ -96,7 +96,6 @@ namespace Velopack.Windows
var pkgDir = Locator.PackagesDir;
var currentDir = Locator.AppContentDir;
var rootAppDirectory = Locator.RootAppDir;
Log.Info($"About to create shortcuts for {relativeExeName}, rootAppDir {rootAppDirectory}");
var pkgPath = Path.Combine(pkgDir, release.OriginalFilename);
var zf = new ZipPackage(pkgPath);
@@ -106,31 +105,11 @@ namespace Velopack.Windows
var ret = new Dictionary<ShortcutLocation, ShellLink>();
foreach (var f in (ShortcutLocation[]) Enum.GetValues(typeof(ShortcutLocation))) {
if (!locations.HasFlag(f)) continue;
var file = LinkTargetForVersionInfo(f, zf, fileVerInfo, rootAppDirectory);
//var appUserModelId = Utility.GetAppUserModelId(zf.Id, exeName);
//var toastActivatorCLSDID = Utility.CreateGuidFromHash(appUserModelId).ToString();
Log.Info($"Creating shortcut for {relativeExeName} => {file}");
//Log.Info($"appUserModelId: {appUserModelId} | toastActivatorCLSID: {toastActivatorCLSDID}");
var target = Path.Combine(rootAppDirectory, relativeExeName);
var sl = new ShellLink {
Target = target,
IconPath = target,
IconIndex = 0,
WorkingDirectory = Path.GetDirectoryName(exePath),
Description = zf.ProductDescription,
};
//if (!String.IsNullOrWhiteSpace(programArguments)) {
// sl.Arguments += String.Format(" -a \"{0}\"", programArguments);
//}
//sl.SetAppUserModelId(appUserModelId);
//sl.SetToastActivatorCLSID(toastActivatorCLSDID);
ret.Add(f, sl);
var file = LinkPathForVersionInfo(f, zf, fileVerInfo, rootAppDirectory);
if (File.Exists(file)) {
Log.Info($"Opening existing shortcut for {relativeExeName} ({file})");
ret.Add(f, new ShellLink(file));
}
}
return ret;
@@ -160,7 +139,7 @@ namespace Velopack.Windows
foreach (var f in (ShortcutLocation[]) Enum.GetValues(typeof(ShortcutLocation))) {
if (!locations.HasFlag(f)) continue;
var file = LinkTargetForVersionInfo(f, zf, fileVerInfo, rootAppDirectory);
var file = LinkPathForVersionInfo(f, zf, fileVerInfo, rootAppDirectory);
var fileExists = File.Exists(file);
// NB: If we've already installed the app, but the shortcut
@@ -222,7 +201,7 @@ namespace Velopack.Windows
foreach (var f in (ShortcutLocation[]) Enum.GetValues(typeof(ShortcutLocation))) {
if (!locations.HasFlag(f)) continue;
var file = LinkTargetForVersionInfo(f, zf, fileVerInfo, rootAppDirectory);
var file = LinkPathForVersionInfo(f, zf, fileVerInfo, rootAppDirectory);
Log.Info($"Removing shortcut for {relativeExeName} => {file}");
try {
if (File.Exists(file)) File.Delete(file);
@@ -235,7 +214,7 @@ namespace Velopack.Windows
/// <summary>
/// Given an <see cref="IPackage"/> and <see cref="FileVersionInfo"/> return the target shortcut path.
/// </summary>
protected virtual string LinkTargetForVersionInfo(ShortcutLocation location, IPackage package, FileVersionInfo versionInfo, string rootdir)
protected virtual string LinkPathForVersionInfo(ShortcutLocation location, IPackage package, FileVersionInfo versionInfo, string rootdir)
{
var possibleProductNames = new[] {
versionInfo.ProductName,
@@ -252,13 +231,13 @@ namespace Velopack.Windows
var prodName = possibleCompanyNames.First(x => !String.IsNullOrWhiteSpace(x));
var pkgName = possibleProductNames.First(x => !String.IsNullOrWhiteSpace(x));
return GetLinkTarget(location, pkgName, prodName, rootdir);
return GetLinkPath(location, pkgName, prodName, rootdir);
}
/// <summary>
/// Given the application info, return the shortcut target path.
/// </summary>
protected virtual string GetLinkTarget(ShortcutLocation location, string title, string applicationName, string rootdir, bool createDirectoryIfNecessary = true)
protected virtual string GetLinkPath(ShortcutLocation location, string title, string applicationName, string rootdir, bool createDirectoryIfNecessary = true)
{
var dir = default(string);

View File

@@ -32,6 +32,22 @@ public static class PathHelper
public static string GetRustAsset(params string[] names)
=> Path.Combine(new string[] { GetRustBuildOutputDir() }.Concat(names).ToArray());
public static string CopyRustAssetTo(string assetName, string dir)
{
var path = GetRustAsset(assetName);
var newPath = Path.Combine(dir, assetName);
File.Copy(path, newPath);
return newPath;
}
public static string CopyFixtureTo(string fixtureName, string dir)
{
var path = GetFixture(fixtureName);
var newPath = Path.Combine(dir, fixtureName);
File.Copy(path, newPath);
return newPath;
}
public static string CopyUpdateTo(string dir)
{
var updateName = "update.exe";

View File

@@ -0,0 +1,55 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Velopack.Locators;
using Velopack.Windows;
namespace Velopack.Tests
{
public class ShortcutTests
{
private readonly ITestOutputHelper _output;
public ShortcutTests(ITestOutputHelper output)
{
_output = output;
}
[SkippableFact]
public void CanCreateAndRemoveShortcuts()
{
Skip.IfNot(VelopackRuntimeInfo.IsWindows);
using var logger = _output.BuildLoggerFor<ShortcutTests>();
string exeName = "NotSquirrelAwareApp.exe";
using var _1 = Utility.GetTempDirectory(out var pkgDir);
using var _2 = Utility.GetTempDirectory(out var appDir);
PathHelper.CopyFixtureTo("AvaloniaCrossPlat-1.0.15-win-full.nupkg", pkgDir);
PathHelper.CopyFixtureTo(exeName, appDir);
var locator = new TestVelopackLocator("AvaloniaCrossPlat", "1.0.0", pkgDir, appDir, appDir, null, logger);
var sh = new Shortcuts(logger, locator);
var flag = ShortcutLocation.StartMenuRoot | ShortcutLocation.Desktop;
sh.DeleteShortcuts(exeName, flag);
sh.CreateShortcut(exeName, flag, false, "");
var shortcuts = sh.FindShortcuts(exeName, flag);
Assert.Equal(2, shortcuts.Keys.Count);
var startDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), "Programs");
var desktopDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
var lnkName = "SquirrelAwareApp.lnk";
var start = shortcuts[ShortcutLocation.StartMenuRoot];
var desktop = shortcuts[ShortcutLocation.Desktop];
Assert.Equal(Path.Combine(startDir, lnkName), start.ShortCutFile);
Assert.Equal(Path.Combine(desktopDir, lnkName), desktop.ShortCutFile);
sh.DeleteShortcuts(exeName, flag);
var after = sh.FindShortcuts(exeName, flag);
Assert.Equal(0, after.Keys.Count);
}
}
}