diff --git a/backend/FwLite/FwLiteDesktop/FwLiteDesktopKernel.cs b/backend/FwLite/FwLiteDesktop/FwLiteDesktopKernel.cs index 2d60edfc2..b3bcda673 100644 --- a/backend/FwLite/FwLiteDesktop/FwLiteDesktopKernel.cs +++ b/backend/FwLite/FwLiteDesktop/FwLiteDesktopKernel.cs @@ -1,4 +1,5 @@ -using Windows.ApplicationModel; +using System.Runtime.InteropServices; +using Windows.ApplicationModel; using FwLiteDesktop.ServerBridge; using FwLiteShared.Auth; using LcmCrdt; @@ -44,9 +45,17 @@ public static void AddFwLiteDesktopServices(this IServiceCollection services, services.AddSingleton(_ => _.GetRequiredService()); services.AddHttpClient(); if (IsPackagedApp) + { services.AddSingleton(); + if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) + { + services.AddSingleton(); + } + } + services.AddSingleton(_ => _.GetRequiredService().WebServices.GetRequiredService()); services.AddSingleton(Preferences.Default); + services.AddSingleton(VersionTracking.Default); configuration.Add(source => source.ServerManager = serverManager); services.AddOptions().BindConfiguration("LocalWebApp"); logging.AddFile(Path.Combine(baseDataPath, "app.log")); diff --git a/backend/FwLite/FwLiteDesktop/MauiProgram.cs b/backend/FwLite/FwLiteDesktop/MauiProgram.cs index ef91d179f..c04d4ede1 100644 --- a/backend/FwLite/FwLiteDesktop/MauiProgram.cs +++ b/backend/FwLite/FwLiteDesktop/MauiProgram.cs @@ -26,6 +26,10 @@ public static MauiApp CreateMauiApp() fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold"); }); + builder.ConfigureEssentials(essentialsBuilder => + { + essentialsBuilder.UseVersionTracking(); + }); builder.ConfigureLifecycleEvents(events => events.AddWindows(windowsEvents => { windowsEvents.OnClosed((window, args) => diff --git a/backend/FwLite/FwLiteDesktop/WindowsShortcutService.cs b/backend/FwLite/FwLiteDesktop/WindowsShortcutService.cs new file mode 100644 index 000000000..b2c855186 --- /dev/null +++ b/backend/FwLite/FwLiteDesktop/WindowsShortcutService.cs @@ -0,0 +1,61 @@ +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using System.Text; +using Windows.ApplicationModel; + +namespace FwLiteDesktop; + +public class WindowsShortcutService(IVersionTracking versionTracking) : IMauiInitializeService +{ + public void Initialize(IServiceProvider services) + { + if (!FwLiteDesktopKernel.IsPackagedApp || !versionTracking.IsFirstLaunchEver || !RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) return; + var package = Package.Current; + IShellLink link = (IShellLink)new ShellLink(); + link.SetPath($@"shell:AppsFolder\{package.Id.FamilyName}!App"); + link.SetIconLocation(Path.Combine(package.InstalledLocation.Path, "logo_light.ico"), 0); + var file = (IPersistFile)link; + file.Save(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Fieldworks Lite.lnk"), + false); + } + + + [ComImport] + [Guid("00021401-0000-0000-C000-000000000046")] + internal class ShellLink + { + } + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("000214F9-0000-0000-C000-000000000046")] + internal interface IShellLink + { + void GetPath([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszFile, + int cchMaxPath, + out IntPtr pfd, + int fFlags); + + void GetIDList(out IntPtr ppidl); + void SetIDList(IntPtr pidl); + void GetDescription([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszName, int cchMaxName); + void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string pszName); + void GetWorkingDirectory([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszDir, int cchMaxPath); + void SetWorkingDirectory([MarshalAs(UnmanagedType.LPWStr)] string pszDir); + void GetArguments([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszArgs, int cchMaxPath); + void SetArguments([MarshalAs(UnmanagedType.LPWStr)] string pszArgs); + void GetHotkey(out short pwHotkey); + void SetHotkey(short wHotkey); + void GetShowCmd(out int piShowCmd); + void SetShowCmd(int iShowCmd); + + void GetIconLocation([Out, MarshalAs(UnmanagedType.LPWStr)] StringBuilder pszIconPath, + int cchIconPath, + out int piIcon); + + void SetIconLocation([MarshalAs(UnmanagedType.LPWStr)] string pszIconPath, int iIcon); + void SetRelativePath([MarshalAs(UnmanagedType.LPWStr)] string pszPathRel, int dwReserved); + void Resolve(IntPtr hwnd, int fFlags); + void SetPath([MarshalAs(UnmanagedType.LPWStr)] string pszFile); + } +}