From b28468e11ea1d7ee238314b6dfe2f9f3d95c3973 Mon Sep 17 00:00:00 2001 From: "Sergey V. Zhdanovskih" Date: Sat, 7 Dec 2024 01:08:33 +0300 Subject: [PATCH] Script to support desktop shortcut creation for portable distributions --- deploy/make_desktop_link.bat | 16 +---- projects/GKCore/GKCore.csproj | 1 + projects/GKCore/GKCore/Shortcut.cs | 89 +++++++++++++++++++++++++++ projects/GKv2/GEDKeeper2/GKProgram.cs | 9 ++- projects/GKv3/GEDKeeper3/GKProgram.cs | 9 ++- 5 files changed, 109 insertions(+), 15 deletions(-) create mode 100644 projects/GKCore/GKCore/Shortcut.cs diff --git a/deploy/make_desktop_link.bat b/deploy/make_desktop_link.bat index 899bb692b..e6cdc6562 100644 --- a/deploy/make_desktop_link.bat +++ b/deploy/make_desktop_link.bat @@ -3,17 +3,7 @@ cls set CUR_DIR=%~dp0 echo Current directory: %CUR_DIR% -if exist "%CUR_DIR%\bin\GEDKeeper2.exe" goto start -goto quit - -:start -set SHRT_LOCA=%userprofile%\Desktop\GEDKeeper2.url -set SHRT_DEST=%CUR_DIR%\bin\GEDKeeper2.exe -echo [InternetShortcut]> %SHRT_LOCA% -echo URL=file:///%SHRT_DEST%>> %SHRT_LOCA% -echo IconFile=%SHRT_DEST%>> %SHRT_LOCA% -echo IconIndex=^0>> %SHRT_LOCA% - -:quit -pause +if exist "%CUR_DIR%\bin\GEDKeeper2.exe" set SHRT_DEST=%CUR_DIR%\bin\GEDKeeper2.exe +if exist "%CUR_DIR%\bin\GEDKeeper3.exe" set SHRT_DEST=%CUR_DIR%\bin\GEDKeeper3.exe +%SHRT_DEST% --createshortcut exit /b 0 diff --git a/projects/GKCore/GKCore.csproj b/projects/GKCore/GKCore.csproj index e68c6ee1c..9161499dd 100644 --- a/projects/GKCore/GKCore.csproj +++ b/projects/GKCore/GKCore.csproj @@ -393,6 +393,7 @@ + diff --git a/projects/GKCore/GKCore/Shortcut.cs b/projects/GKCore/GKCore/Shortcut.cs new file mode 100644 index 000000000..ecd5bfaea --- /dev/null +++ b/projects/GKCore/GKCore/Shortcut.cs @@ -0,0 +1,89 @@ +/* + * "GEDKeeper", the personal genealogical database editor. + * Copyright (C) 2009-2024 by Sergey V. Zhdanovskih. + * + * This file is part of "GEDKeeper". + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#if OS_MSWIN + +using System; +using System.IO; +using System.Runtime.InteropServices; +using System.Runtime.InteropServices.ComTypes; +using System.Text; +using GKCore; + +namespace GKUI.Platform +{ + /// + /// For portable distributions. + /// + public class ShellLinkTool + { + public static bool HasArg(string[] args) + { + return Array.IndexOf(args, "--createshortcut") >= 0; + } + + public static void CreateShortcut() + { + var exeName = GKUtils.GetBinPath() + "GEDKeeper3.exe"; + + IShellLink link = (IShellLink)new ShellLink(); + link.SetPath(exeName); + + var file = (IPersistFile)link; + string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory); + file.Save(Path.Combine(desktopPath, "GEDKeeper3.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); + } +} + +#endif diff --git a/projects/GKv2/GEDKeeper2/GKProgram.cs b/projects/GKv2/GEDKeeper2/GKProgram.cs index 54b95f69d..e02098aed 100644 --- a/projects/GKv2/GEDKeeper2/GKProgram.cs +++ b/projects/GKv2/GEDKeeper2/GKProgram.cs @@ -1,6 +1,6 @@ /* * "GEDKeeper", the personal genealogical database editor. - * Copyright (C) 2009-2022 by Sergey V. Zhdanovskih. + * Copyright (C) 2009-2024 by Sergey V. Zhdanovskih. * * This file is part of "GEDKeeper". * @@ -44,6 +44,13 @@ public static class GKProgram [SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlAppDomain)] public static void Main(string[] args) { +#if OS_MSWIN + if (ShellLinkTool.HasArg(args)) { + ShellLinkTool.CreateShortcut(); + return; + } +#endif + WFAppHost.Startup(args); using (var tracker = new SingleInstanceTracker(GKData.APP_TITLE, AppHost.GetSingleInstanceEnforcer)) { diff --git a/projects/GKv3/GEDKeeper3/GKProgram.cs b/projects/GKv3/GEDKeeper3/GKProgram.cs index dcf53de97..e38666941 100644 --- a/projects/GKv3/GEDKeeper3/GKProgram.cs +++ b/projects/GKv3/GEDKeeper3/GKProgram.cs @@ -1,6 +1,6 @@ /* * "GEDKeeper", the personal genealogical database editor. - * Copyright (C) 2009-2022 by Sergey V. Zhdanovskih. + * Copyright (C) 2009-2024 by Sergey V. Zhdanovskih. * * This file is part of "GEDKeeper". * @@ -48,6 +48,13 @@ public static class GKProgram [STAThread] public static void Main(string[] args) { +#if OS_MSWIN + if (ShellLinkTool.HasArg(args)) { + ShellLinkTool.CreateShortcut(); + return; + } +#endif + EtoAppHost.Startup(args); var application = new Application();