diff --git a/TerraAngel.Installer/Program.cs b/TerraAngel.Installer/Program.cs index 82ea7a7..f2b44c0 100644 --- a/TerraAngel.Installer/Program.cs +++ b/TerraAngel.Installer/Program.cs @@ -44,6 +44,7 @@ public class SetupSettings private static void Main(string[] args) { + Console.ReadLine(); if (args.Length == 0) { List sdks = SDKUtility.GetDotnetSDKList(); @@ -193,9 +194,18 @@ private static void HandleNewInstallation(ReleaseDownloader.ReleaseRoot release, foreach (LocalPath path in DirectoryUtility.EnumerateFiles(buildDir)) { + string dirInInstaller = Path.GetDirectoryName(Path.Combine(defaultIntsallDirectory, path.RelativePath))!; + + if (!Directory.Exists(dirInInstaller)) + { + Directory.CreateDirectory(dirInInstaller); + } + File.Copy(path.FullPath, Path.Combine(defaultIntsallDirectory, path.RelativePath), true); } + SetCurrentInstallation(new Installation(latestReleaseVersion, buildDir)); + string terraAngelFilePath = Path.Combine(defaultIntsallDirectory, "TerraAngel.exe"); // Incase the assembly isn't named correctly @@ -215,17 +225,8 @@ private static void HandleNewInstallation(ReleaseDownloader.ReleaseRoot release, string startMenuPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu), "Programs", "TerraAngel.lnk"); string desktopPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), "TerraAngel.lnk"); - string[] shortcutLines = new string[] - { - "[InternetShortcut]", - $"URL=file:///{terraAngelFilePath}", - "IconIndex=0", - $"IconFile={terraAngelFilePath}" - }; - try { - if (File.Exists(startMenuPath)) { File.Delete(startMenuPath); @@ -236,13 +237,12 @@ private static void HandleNewInstallation(ReleaseDownloader.ReleaseRoot release, File.Delete(desktopPath); } - File.WriteAllLines(startMenuPath, shortcutLines); - - File.WriteAllLines(desktopPath, shortcutLines); + WindowsShortcutUtility.CreateShortcut(terraAngelFilePath, defaultIntsallDirectory, startMenuPath); + WindowsShortcutUtility.CreateShortcut(terraAngelFilePath, defaultIntsallDirectory, desktopPath); } catch { - Console.WriteLine("Failed to create shortcuts to application"); + Console.WriteLine("Failed to create shortcuts D:"); } } @@ -296,9 +296,18 @@ private static void HandleUpdate(ReleaseDownloader.ReleaseRoot release, Version foreach (LocalPath path in DirectoryUtility.EnumerateFiles(buildDir)) { + string dirInInstaller = Path.GetDirectoryName(Path.Combine(previousInstall.InstallationRoot, path.RelativePath))!; + + if (!Directory.Exists(dirInInstaller)) + { + Directory.CreateDirectory(dirInInstaller); + } + File.Copy(path.FullPath, Path.Combine(previousInstall.InstallationRoot, path.RelativePath), true); } + SetCurrentInstallation(new Installation(latestReleaseVersion, buildDir)); + Console.WriteLine($"Successfully updated TerraAngel to v{latestReleaseVersion}"); Console.Write("Press enter to exit..."); Console.ReadLine(); @@ -385,8 +394,6 @@ private static bool TryBuild(ReleaseDownloader.ReleaseRoot release, Version late return false; } - SetCurrentInstallation(new Installation(latestReleaseVersion, buildDir)); - Console.WriteLine($"Build succeeded in {sw.Elapsed.TotalSeconds}s"); return true; @@ -455,7 +462,7 @@ private static bool CheckPermission() File.Delete(testFileDir); } - File.Create(testFileDir); + File.Create(testFileDir).Dispose(); if (File.Exists(testFileDir)) { diff --git a/TerraAngel.Installer/WindowsShortcutUtility.cs b/TerraAngel.Installer/WindowsShortcutUtility.cs new file mode 100644 index 0000000..eb709d3 --- /dev/null +++ b/TerraAngel.Installer/WindowsShortcutUtility.cs @@ -0,0 +1,70 @@ +using System.Runtime.InteropServices; +using System.Text; + +namespace TerraAngel.Installer; + +internal class WindowsShortcutUtility +{ + public static void CreateShortcut(string targetApp, string workingDirectory, string outputFile) + { + IShellLink link = (IShellLink)new ShellLink(); + + link.SetPath(targetApp); + link.SetWorkingDirectory(workingDirectory); + + IPersistFile file = (IPersistFile)link; + file.Save(outputFile, false); + } + + [ComImport] + [Guid("00021401-0000-0000-C000-000000000046")] + private class ShellLink + { + + } + + [ComImport] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + [Guid("000214F9-0000-0000-C000-000000000046")] + private 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); + } + + [ComImport()] + [Guid("0000010B-0000-0000-C000-000000000046")] + [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] + private interface IPersistFile + { + [PreserveSig] + int GetClassID(out Guid pClassID); + + [PreserveSig] + int IsDirty(); + + void Load([MarshalAs(UnmanagedType.LPWStr)] string pszFileName, uint dwMode); + + void Save([MarshalAs(UnmanagedType.LPWStr)] string pszFileName, [MarshalAs(UnmanagedType.Bool)] bool fRemember); + + void SaveCompleted([MarshalAs(UnmanagedType.LPWStr)] string pszFileName); + + void GetCurFile([Out, MarshalAs(UnmanagedType.LPWStr)] out string ppszFileName); + } +}