fix(installer): skip rewriting the autostart shortcut when already current
RegisterAutostartStep rewrote the Startup .lnk on every install/update/repair even when it already pointed at the right worker exe. AutostartShortcut.Install now reads the existing shortcut's target via ShortcutFactory.TryGetTarget and skips the rewrite when it matches, reporting the skip in progress output. Legacy service/scheduled-task cleanup stays unconditional (migration safety net).
This commit is contained in:
@@ -11,13 +11,26 @@ public static class AutostartShortcut
|
||||
|
||||
public static string PathIn(string startupDir) => Path.Combine(startupDir, FileName);
|
||||
|
||||
public static void Install(string startupDir, string workerExe)
|
||||
/// <summary>Creates or updates the Startup shortcut. Returns false if it already pointed at <paramref name="workerExe"/> and was left untouched.</summary>
|
||||
public static bool Install(string startupDir, string workerExe)
|
||||
{
|
||||
Directory.CreateDirectory(startupDir);
|
||||
var shortcutPath = PathIn(startupDir);
|
||||
if (File.Exists(shortcutPath))
|
||||
{
|
||||
var existingTarget = ShortcutFactory.TryGetTarget(shortcutPath);
|
||||
if (existingTarget is not null && PathsEqual(existingTarget, workerExe))
|
||||
return false;
|
||||
}
|
||||
|
||||
var workingDir = Path.GetDirectoryName(workerExe) ?? startupDir;
|
||||
ShortcutFactory.CreateShortcut(PathIn(startupDir), workerExe, workingDir, "ClaudeDo background worker");
|
||||
ShortcutFactory.CreateShortcut(shortcutPath, workerExe, workingDir, "ClaudeDo background worker");
|
||||
return true;
|
||||
}
|
||||
|
||||
private static bool PathsEqual(string a, string b) =>
|
||||
string.Equals(Path.GetFullPath(a), Path.GetFullPath(b), StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
public static void Remove(string startupDir)
|
||||
{
|
||||
var path = PathIn(startupDir);
|
||||
|
||||
@@ -6,6 +6,8 @@ namespace ClaudeDo.Installer.Core;
|
||||
|
||||
public static class ShortcutFactory
|
||||
{
|
||||
private const int SlgpRawPath = 0x4;
|
||||
|
||||
public static void CreateShortcut(string shortcutPath, string targetPath, string workingDir, string description)
|
||||
{
|
||||
var link = (IShellLink)new ShellLink();
|
||||
@@ -18,6 +20,24 @@ public static class ShortcutFactory
|
||||
file.Save(shortcutPath, false);
|
||||
}
|
||||
|
||||
/// <summary>Reads the target path of an existing .lnk, or null if it can't be read (missing/corrupt).</summary>
|
||||
public static string? TryGetTarget(string shortcutPath)
|
||||
{
|
||||
try
|
||||
{
|
||||
var link = (IShellLink)new ShellLink();
|
||||
((IPersistFile)link).Load(shortcutPath, 0);
|
||||
var sb = new StringBuilder(260);
|
||||
link.GetPath(sb, sb.Capacity, IntPtr.Zero, SlgpRawPath);
|
||||
var path = sb.ToString();
|
||||
return path.Length == 0 ? null : path;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
[ComImport]
|
||||
[Guid("00021401-0000-0000-C000-000000000046")]
|
||||
private class ShellLink { }
|
||||
|
||||
Reference in New Issue
Block a user