Implement autostart functionality, ZIP packaging, and related installation scripts; update documentation and tests
This commit is contained in:
+15
-2
@@ -5,7 +5,8 @@ using MusicBridge.Agent.Network;
|
||||
namespace MusicBridge.Agent.Desktop;
|
||||
|
||||
internal sealed class DesktopHost(Func<MediaState> read, IMediaService media, PairingService pairing,
|
||||
Func<string> network, Action showQr, Action exit, bool visible = true) : IDisposable
|
||||
Func<string> network, Action showQr, Action exit, bool visible = true,
|
||||
StartupSettings? startup = null, bool minimized = false) : IDisposable
|
||||
{
|
||||
private readonly object gate = new();
|
||||
private readonly TaskCompletionSource ready = new(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
@@ -34,6 +35,18 @@ internal sealed class DesktopHost(Func<MediaState> read, IMediaService media, Pa
|
||||
menu.Items.Add("Открыть MusicBridge", null, (_, _) => ShowWindow());
|
||||
var toggle = menu.Items.Add("Play / Pause", null, async (_, _) => await view.SendAsync(new("toggle")));
|
||||
menu.Items.Add("Подключить iPhone", null, (_, _) => { pairing.Open(); showQr(); });
|
||||
if (startup is not null)
|
||||
{
|
||||
var autoStart = new ToolStripMenuItem("Запускать вместе с Windows");
|
||||
try { autoStart.Checked = startup.Enabled; }
|
||||
catch (Exception) { autoStart.Enabled = false; }
|
||||
autoStart.Click += (_, _) =>
|
||||
{
|
||||
try { startup.SetEnabled(!startup.Enabled); autoStart.Checked = startup.Enabled; }
|
||||
catch (Exception ex) { MessageBox.Show(view, ex.Message, "Автозапуск MusicBridge", MessageBoxButtons.OK, MessageBoxIcon.Warning); }
|
||||
};
|
||||
menu.Items.Add(autoStart);
|
||||
}
|
||||
menu.Items.Add(new ToolStripSeparator());
|
||||
menu.Items.Add("Завершить MusicBridge", null, (_, _) => { view.AllowClose = true; view.Close(); });
|
||||
using var icon = new NotifyIcon { Icon = SystemIcons.Application, Text = "MusicBridge", ContextMenuStrip = menu, Visible = visible };
|
||||
@@ -46,7 +59,7 @@ internal sealed class DesktopHost(Func<MediaState> read, IMediaService media, Pa
|
||||
var text = state.HasSession ? $"MusicBridge — {state.Title}" : "MusicBridge — нет плеера";
|
||||
icon.Text = text.Length > 63 ? text[..63] : text;
|
||||
};
|
||||
view.Shown += (_, _) => { timer.Start(); ready.TrySetResult(); };
|
||||
view.Shown += (_, _) => { if (minimized) view.Hide(); timer.Start(); ready.TrySetResult(); };
|
||||
lock (gate)
|
||||
{
|
||||
if (disposed) { ready.TrySetCanceled(); return; }
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace MusicBridge.Agent.Desktop;
|
||||
|
||||
internal sealed class StartupSettings(string executable, bool lan, int port,
|
||||
string registryPath = @"Software\Microsoft\Windows\CurrentVersion\Run")
|
||||
{
|
||||
private const string ValueName = "MusicBridge.Agent";
|
||||
public string Command => BuildCommand(executable, lan, port);
|
||||
public bool Enabled
|
||||
{
|
||||
get
|
||||
{
|
||||
using var key = Registry.CurrentUser.OpenSubKey(registryPath);
|
||||
return string.Equals(key?.GetValue(ValueName) as string, Command, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
||||
public void SetEnabled(bool enabled)
|
||||
{
|
||||
if (enabled && !File.Exists(executable)) throw new FileNotFoundException("Сначала установи или опубликуй MusicBridge.", executable);
|
||||
using var key = Registry.CurrentUser.CreateSubKey(registryPath);
|
||||
if (enabled) key.SetValue(ValueName, Command, RegistryValueKind.String);
|
||||
else key.DeleteValue(ValueName, throwOnMissingValue: false);
|
||||
}
|
||||
|
||||
internal static string BuildCommand(string executable, bool lan, int port)
|
||||
{
|
||||
if (!Path.IsPathFullyQualified(executable) || executable.Contains('"') || executable.Any(char.IsControl)
|
||||
|| !Path.GetFileName(executable).Equals("MusicBridge.Agent.exe", StringComparison.OrdinalIgnoreCase)
|
||||
|| port is < 1 or > 65535) throw new ArgumentException("Неверный путь или порт автозапуска.");
|
||||
return $"\"{executable}\" --tray --minimized{(lan ? " --lan" : "")} --port {port}";
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user