Browse Source

Fixed licenses and cache

Krzysztof Krysiński 6 months ago
parent
commit
b56a4ab888

+ 60 - 8
src/PixiEditor.Builder/build/PackageBuilders/DotAppPackageBuilder.cs

@@ -1,8 +1,14 @@
 using System;
 using System;
+using System.Diagnostics;
 using System.IO;
 using System.IO;
 using System.Reflection;
 using System.Reflection;
+using System.Text;
 using System.Xml.Linq;
 using System.Xml.Linq;
+using Cake.Common;
+using Cake.Common.IO;
 using Cake.Core.Diagnostics;
 using Cake.Core.Diagnostics;
+using Cake.Core.IO;
+using Path = System.IO.Path;
 
 
 namespace PixiEditor.Cake.Builder.PackageBuilders;
 namespace PixiEditor.Cake.Builder.PackageBuilders;
 
 
@@ -11,6 +17,7 @@ public sealed class DotAppPackageBuilder : PackageBuilder
 {
 {
     public override PackageBuildInfo BuildPackage(BuildContext context)
     public override PackageBuildInfo BuildPackage(BuildContext context)
     {
     {
+        string universalBinPath = CombineUniversalBinary(context);
         string plistPath = Path.Combine(context.PackageProjectPath, "Info.plist");
         string plistPath = Path.Combine(context.PackageProjectPath, "Info.plist");
 
 
         if (!File.Exists(plistPath))
         if (!File.Exists(plistPath))
@@ -19,7 +26,8 @@ public sealed class DotAppPackageBuilder : PackageBuilder
         }
         }
 
 
         string packagePath = Path.Combine(context.OutputDirectory, "package");
         string packagePath = Path.Combine(context.OutputDirectory, "package");
-        
+        CreateDirectoryIfMissing(packagePath);
+
         string path = Path.Combine(packagePath, "PixiEditor.app");
         string path = Path.Combine(packagePath, "PixiEditor.app");
         CreateDirectoryIfMissing(path);
         CreateDirectoryIfMissing(path);
 
 
@@ -35,17 +43,17 @@ public sealed class DotAppPackageBuilder : PackageBuilder
         string codeSignaturesPath = Path.Combine(contentsPath, "_CodeSignature");
         string codeSignaturesPath = Path.Combine(contentsPath, "_CodeSignature");
         CreateDirectoryIfMissing(codeSignaturesPath);
         CreateDirectoryIfMissing(codeSignaturesPath);
 
 
-        string dllContentsPath = context.OutputDirectory;
+        string dllContentsPath = universalBinPath;
         CopyFilesOverwrite(dllContentsPath, macOsPath, true, packagePath);
         CopyFilesOverwrite(dllContentsPath, macOsPath, true, packagePath);
-        
+
         string pilst = File.ReadAllText(plistPath);
         string pilst = File.ReadAllText(plistPath);
-        
-        var assembly = Assembly.LoadFile(Path.Combine(dllContentsPath, "PixiEditor.dll"));
-        
-        pilst = pilst.Replace("{version-string}", assembly.GetName().Version.ToString());
+
+        string version = ReadVersionFile(context.VersionFile);
+
+        pilst = pilst.Replace("{version-string}", version);
 
 
         string targetPilstPath = Path.Combine(contentsPath, "Info.plist");
         string targetPilstPath = Path.Combine(contentsPath, "Info.plist");
-        
+
         File.WriteAllText(targetPilstPath, pilst);
         File.WriteAllText(targetPilstPath, pilst);
 
 
         File.Copy(Path.Combine(context.PackageProjectPath, "PixiEditor.icns"),
         File.Copy(Path.Combine(context.PackageProjectPath, "PixiEditor.icns"),
@@ -53,4 +61,48 @@ public sealed class DotAppPackageBuilder : PackageBuilder
 
 
         return PackageBuildInfo.Succeed(path);
         return PackageBuildInfo.Succeed(path);
     }
     }
+
+    private string ReadVersionFile(string path)
+    {
+        if (string.IsNullOrEmpty(path))
+        {
+            throw new ArgumentNullException(nameof(path));
+        }
+
+        if (!File.Exists(path))
+        {
+            throw new FileNotFoundException("Version file not found", path);
+        }
+
+        string[] assemblyInfo = File.ReadAllLines(path);
+
+        for (int i = assemblyInfo.Length - 1; i >= 0; i--)
+        {
+            string line = assemblyInfo[i];
+            if (line.Contains("AssemblyVersion"))
+            {
+                return line.Split('"')[1];
+            }
+        }
+
+        throw new InvalidOperationException("Version not found in version file");
+    }
+
+    private string CombineUniversalBinary(BuildContext context)
+    {
+        string outputPath = Path.Combine(context.OutputDirectory, "universal");
+        CreateDirectoryIfMissing(outputPath);
+
+        StringBuilder args = new StringBuilder();
+        args.Append($"-output {Path.Combine(outputPath, "PixiEditor")} ");
+        args.Append("-create ");
+        foreach (var dir in context.FinalOutputDirectories)
+        {
+            args.Append($"{Path.Combine(dir, "PixiEditor")} ");
+        }
+
+        context.StartProcess("lipo", $"-create {args}");
+
+        return outputPath;
+    }
 }
 }

+ 6 - 0
src/PixiEditor.Builder/build/PackageBuilders/PackageBuilder.cs

@@ -31,6 +31,12 @@ public abstract class PackageBuilder
         foreach (string file in Directory.GetFiles(sourcePath))
         foreach (string file in Directory.GetFiles(sourcePath))
         {
         {
             string fileName = Path.GetFileName(file);
             string fileName = Path.GetFileName(file);
+
+            if (fileName == ignore)
+            {
+                continue;
+            }
+
             string destFile = Path.Combine(destinationPath, fileName);
             string destFile = Path.Combine(destinationPath, fileName);
             File.Copy(file, destFile, true);
             File.Copy(file, destFile, true);
         }
         }

+ 73 - 15
src/PixiEditor.Builder/build/Program.cs

@@ -51,6 +51,14 @@ public class BuildContext : FrostingContext
 
 
     public string PackageProjectPath { get; set; }
     public string PackageProjectPath { get; set; }
 
 
+    public bool PublishReadyToRun { get; set; } = false;
+
+    public bool SingleFile { get; set; } = false;
+
+    public string VersionFile { get; set; }
+
+    public string[] FinalOutputDirectories { get; set; }
+
     public BuildContext(ICakeContext context)
     public BuildContext(ICakeContext context)
         : base(context)
         : base(context)
     {
     {
@@ -89,12 +97,19 @@ public class BuildContext : FrostingContext
 
 
         PackageProjectPath = context.Arguments.GetArgument("package-proj-path");
         PackageProjectPath = context.Arguments.GetArgument("package-proj-path");
 
 
+        PublishReadyToRun = context.Arguments.HasArgument("ready-to-run");
+
+        SingleFile = context.Arguments.HasArgument("single-file");
+
+        VersionFile = context.Arguments.GetArgument("version-file");
+
         if (BuildPackage)
         if (BuildPackage)
         {
         {
             PackageType = context.Arguments.GetArgument("build-package");
             PackageType = context.Arguments.GetArgument("build-package");
             if (string.Equals(PackageType, "DotApp", StringComparison.CurrentCultureIgnoreCase))
             if (string.Equals(PackageType, "DotApp", StringComparison.CurrentCultureIgnoreCase))
             {
             {
                 UseAppHost = true;
                 UseAppHost = true;
+                SelfContained = true;
             }
             }
 
 
             if (string.IsNullOrEmpty(PackageProjectPath))
             if (string.IsNullOrEmpty(PackageProjectPath))
@@ -159,19 +174,58 @@ public sealed class BuildProjectTask : FrostingTask<BuildContext>
         context.Log.Information("Building project...");
         context.Log.Information("Building project...");
         string projectPath = context.PathToProject;
         string projectPath = context.PathToProject;
 
 
-        var settings = new DotNetPublishSettings()
+        bool multipleRuntimes = context.Runtime.Contains(';');
+
+        string[] runtimes = multipleRuntimes ? context.Runtime.Split(';') : new[] { context.Runtime };
+
+        context.FinalOutputDirectories = new string[runtimes.Length];
+
+        for (var i = 0; i < runtimes.Length; i++)
         {
         {
-            Configuration = context.BuildConfiguration,
-            SelfContained = context.SelfContained,
-            Runtime = context.Runtime,
-            MSBuildSettings = new DotNetMSBuildSettings()
+            var runtime = runtimes[i];
+            string finalDir = multipleRuntimes
+                ? Path.Combine(context.OutputDirectory, runtime)
+                : context.OutputDirectory;
+
+            context.FinalOutputDirectories[i] = finalDir;
+
+            var settings = new DotNetPublishSettings()
             {
             {
-                Properties = { ["UseAppHost"] = [context.UseAppHost.ToString()] },
-            },
-            OutputDirectory = context.OutputDirectory,
-        };
+                Configuration = context.BuildConfiguration,
+                SelfContained = context.SelfContained,
+                Runtime = runtime,
+                PublishReadyToRun = context.PublishReadyToRun,
+                PublishSingleFile = context.SingleFile,
+                IncludeAllContentForSelfExtract = context.SingleFile,
+                IncludeNativeLibrariesForSelfExtract = context.SingleFile,
+                MSBuildSettings = new DotNetMSBuildSettings()
+                {
+                    Properties =
+                    {
+                        { "UseAppHost", [context.UseAppHost.ToString()] }, { "RuntimeIdentifier", [runtime] },
+                    },
+                },
+                OutputDirectory = finalDir,
+            };
+
+            context.DotNetPublish(projectPath, settings);
+            RenameExecutable(finalDir, !runtime.StartsWith("win"));
+        }
+    }
+
+    private void RenameExecutable(string finalDir, bool isUnix)
+    {
+        string executablePath = Path.Combine(finalDir, "PixiEditor.Desktop");
+        if (!isUnix)
+        {
+            executablePath += ".exe";
+        }
 
 
-        context.DotNetPublish(projectPath, settings);
+        if (File.Exists(executablePath))
+        {
+            string finalName = isUnix ? "PixiEditor" : "PixiEditor.Desktop";
+            File.Move(executablePath, Path.Combine(finalDir, finalName), true);
+        }
     }
     }
 
 
     public override void Finally(BuildContext context)
     public override void Finally(BuildContext context)
@@ -190,6 +244,7 @@ public sealed class BuildExtensionsTask : FrostingTask<BuildContext>
     public override void Run(BuildContext context)
     public override void Run(BuildContext context)
     {
     {
         context.Log.Information("Building extensions...");
         context.Log.Information("Building extensions...");
+
         foreach (var project in context.ExtensionProjectsToInclude)
         foreach (var project in context.ExtensionProjectsToInclude)
         {
         {
             var settings = new DotNetPublishSettings() { Configuration = context.BuildConfiguration, };
             var settings = new DotNetPublishSettings() { Configuration = context.BuildConfiguration, };
@@ -206,13 +261,16 @@ public sealed class CopyExtensionsTask : FrostingTask<BuildContext>
     public override void Run(BuildContext context)
     public override void Run(BuildContext context)
     {
     {
         context.Log.Information("Copying extensions...");
         context.Log.Information("Copying extensions...");
-        foreach (var project in context.ExtensionProjectsToInclude)
+        foreach (var buildDir in context.FinalOutputDirectories)
         {
         {
-            string outputDir = Path.Combine(context.OutputDirectory, "Extensions");
-            string sourceDir = Path.Combine(project, "bin",
-                context.BuildConfiguration, "wasi-wasm", "Extensions");
+            foreach (var project in context.ExtensionProjectsToInclude)
+            {
+                string outputDir = Path.Combine(buildDir, "Extensions");
+                string sourceDir = Path.Combine(project, "bin",
+                    context.BuildConfiguration, "wasi-wasm", "Extensions");
 
 
-            CopyDirectoryContents(sourceDir, outputDir, context);
+                CopyDirectoryContents(sourceDir, outputDir, context);
+            }
         }
         }
     }
     }
 
 

+ 3 - 1
src/PixiEditor.Desktop/Info.plist

@@ -5,7 +5,7 @@
         <key>CFBundleName</key>
         <key>CFBundleName</key>
         <string>PixiEditor</string>
         <string>PixiEditor</string>
         <key>CFBundleDisplayName</key>
         <key>CFBundleDisplayName</key>
-        <string>PixiEditor.Desktop</string>
+        <string>PixiEditor</string>
         <key>CFBundleIdentifier</key>
         <key>CFBundleIdentifier</key>
         <string>com.pixieditor.macos</string>
         <string>com.pixieditor.macos</string>
         <key>CFBundleVersion</key>
         <key>CFBundleVersion</key>
@@ -18,6 +18,8 @@
         <string>PixiEditor.icns</string>
         <string>PixiEditor.icns</string>
         <key>CFBundleShortVersionString</key>
         <key>CFBundleShortVersionString</key>
         <string>{version-string}</string>
         <string>{version-string}</string>
+        <key>CFBundleSignature</key>
+        <string>????</string>
         <key>NSPrincipalClass</key>
         <key>NSPrincipalClass</key>
         <string>NSApplication</string>
         <string>NSApplication</string>
         <key>NSHighResolutionCapable</key>
         <key>NSHighResolutionCapable</key>

+ 0 - 13
src/PixiEditor.Desktop/PixiEditor.Desktop.csproj

@@ -29,10 +29,6 @@
     <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.11.0"/>
     <PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.11.0"/>
   </ItemGroup>
   </ItemGroup>
 
 
-  <ItemGroup Condition="$([MSBuild]::IsOsPlatform('OSX'))">
-    <PackageReference Include="Dotnet.Bundle" Version="0.9.13"/>
-  </ItemGroup>
-
   <ItemGroup>
   <ItemGroup>
     <None Include="..\PixiEditor\Images\favicon.ico">
     <None Include="..\PixiEditor\Images\favicon.ico">
       <Link>favicon.ico</Link>
       <Link>favicon.ico</Link>
@@ -43,13 +39,4 @@
     <ProjectReference Include="..\PixiEditor\PixiEditor.csproj"/>
     <ProjectReference Include="..\PixiEditor\PixiEditor.csproj"/>
   </ItemGroup>
   </ItemGroup>
 
 
-  <Target Name="Rename" AfterTargets="AfterBuild" Condition="$([MSBuild]::IsOsPlatform('Windows'))">
-    <Move SourceFiles="$(OutDir)PixiEditor.Desktop.exe" DestinationFiles="$(OutDir)PixiEditor.exe"/>
-    <Message Text="Renamed build executable file." Importance="high"/>
-  </Target>
-
-  <Target Name="Rename" AfterTargets="Publish" Condition="$([MSBuild]::IsOsPlatform('Windows'))">
-    <Move SourceFiles="$(PublishDir)PixiEditor.Desktop.exe" DestinationFiles="$(PublishDir)PixiEditor.exe"/>
-    <Message Text="Renamed published executable file." Importance="high"/>
-  </Target>
 </Project>
 </Project>

+ 11 - 1
src/PixiEditor.Linux/LinuxOperatingSystem.cs

@@ -23,11 +23,21 @@ public sealed class LinuxOperatingSystem : IOperatingSystem
         throw new NotImplementedException();
         throw new NotImplementedException();
     }
     }
 
 
-    public bool HandleNewInstance(Dispatcher? dispatcher, Action<string> openInExistingAction, IApplicationLifetime lifetime)
+    public bool HandleNewInstance(Dispatcher? dispatcher, Action<string, bool> openInExistingAction, IApplicationLifetime lifetime)
     {
     {
         return true;
         return true;
     }
     }
 
 
+    public void HandleActivatedWithFile(FileActivatedEventArgs fileActivatedEventArgs)
+    {
+        throw new NotImplementedException();
+    }
+
+    public void HandleActivatedWithUri(ProtocolActivatedEventArgs openUriEventArgs)
+    {
+        throw new NotImplementedException();
+    }
+
     class LinuxOSInformation
     class LinuxOSInformation
     {
     {
         const string FilePath = "/etc/os-release";
         const string FilePath = "/etc/os-release";

+ 43 - 2
src/PixiEditor.MacOs/MacOperatingSystem.cs

@@ -1,4 +1,5 @@
-using Avalonia.Controls.ApplicationLifetimes;
+using System.Text;
+using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Threading;
 using Avalonia.Threading;
 using PixiEditor.OperatingSystem;
 using PixiEditor.OperatingSystem;
 
 
@@ -12,6 +13,9 @@ public sealed class MacOperatingSystem : IOperatingSystem
     
     
     public IInputKeys InputKeys { get; } = new MacOsInputKeys();
     public IInputKeys InputKeys { get; } = new MacOsInputKeys();
     public IProcessUtility ProcessUtility { get; } = new MacOsProcessUtility();
     public IProcessUtility ProcessUtility { get; } = new MacOsProcessUtility();
+
+    private List<Uri> activationUris;
+    
     public void OpenUri(string uri)
     public void OpenUri(string uri)
     {
     {
         ProcessUtility.ShellExecute(uri);
         ProcessUtility.ShellExecute(uri);
@@ -22,8 +26,45 @@ public sealed class MacOperatingSystem : IOperatingSystem
         ProcessUtility.ShellExecute(Path.GetDirectoryName(path));
         ProcessUtility.ShellExecute(Path.GetDirectoryName(path));
     }
     }
 
 
-    public bool HandleNewInstance(Dispatcher? dispatcher, Action<string> openInExistingAction, IApplicationLifetime lifetime)
+    public bool HandleNewInstance(Dispatcher? dispatcher, Action<string, bool> openInExistingAction, IApplicationLifetime lifetime)
     {
     {
+        StringBuilder args = new StringBuilder();
+        
+        if(activationUris != null)
+        {
+            foreach (var uri in activationUris)
+            {
+                args.Append('"');
+                args.Append(uri.AbsolutePath);
+                args.Append('"');
+                args.Append(' ');
+            }
+        }
+        
+        dispatcher.Invoke(() => openInExistingAction(args.ToString(), true));
         return true;
         return true;
     }
     }
+
+    public void HandleActivatedWithFile(FileActivatedEventArgs fileActivatedEventArgs)
+    {
+        if(activationUris == null)
+        {
+            activationUris = [];
+        }
+        
+        foreach (var file in fileActivatedEventArgs.Files)
+        {
+           activationUris.Add(file.Path);
+        }
+    }
+
+    public void HandleActivatedWithUri(ProtocolActivatedEventArgs openUriEventArgs)
+    {
+        if(activationUris == null)
+        {
+            activationUris = [];
+        }
+        
+        activationUris.Add(openUriEventArgs.Uri);
+    }
 }
 }

+ 1 - 0
src/PixiEditor.MacOs/todo.md

@@ -8,4 +8,5 @@
 - [x] Process handling
 - [x] Process handling
 - [ ] Check if extensions work
 - [ ] Check if extensions work
 - [ ] Native menu
 - [ ] Native menu
+- [ ] Crash dialog
 - [ ] Performance fixes
 - [ ] Performance fixes

+ 3 - 1
src/PixiEditor.OperatingSystem/IOperatingSystem.cs

@@ -30,5 +30,7 @@ public interface IOperatingSystem
 
 
     public void OpenUri(string uri);
     public void OpenUri(string uri);
     public void OpenFolder(string path);
     public void OpenFolder(string path);
-    public bool HandleNewInstance(Dispatcher? dispatcher, Action<string> openInExistingAction, IApplicationLifetime lifetime);
+    public bool HandleNewInstance(Dispatcher? dispatcher, Action<string, bool> openInExistingAction, IApplicationLifetime lifetime);
+    public void HandleActivatedWithFile(FileActivatedEventArgs fileActivatedEventArgs);
+    public void HandleActivatedWithUri(ProtocolActivatedEventArgs openUriEventArgs);
 }
 }

+ 7 - 3
src/PixiEditor.Windows/WindowsOperatingSystem.cs

@@ -51,7 +51,7 @@ public sealed class WindowsOperatingSystem : IOperatingSystem
         WindowsProcessUtility.ShellExecuteEV(dirName);
         WindowsProcessUtility.ShellExecuteEV(dirName);
     }
     }
 
 
-    public bool HandleNewInstance(Dispatcher? dispatcher, Action<string> openInExistingAction, IApplicationLifetime lifetime)
+    public bool HandleNewInstance(Dispatcher? dispatcher, Action<string, bool> openInExistingAction, IApplicationLifetime lifetime)
     {
     {
         bool isOwned;
         bool isOwned;
         _mutex = new Mutex(true, UniqueMutexName, out isOwned);
         _mutex = new Mutex(true, UniqueMutexName, out isOwned);
@@ -69,7 +69,7 @@ public sealed class WindowsOperatingSystem : IOperatingSystem
                 {
                 {
                     while (_eventWaitHandle.WaitOne())
                     while (_eventWaitHandle.WaitOne())
                     {
                     {
-                        dispatcher.Invoke(() => openInExistingAction(passedArgsFile));
+                        dispatcher.Invoke(() => openInExistingAction(passedArgsFile, false));
                     }
                     }
                 })
                 })
             {
             {
@@ -89,7 +89,11 @@ public sealed class WindowsOperatingSystem : IOperatingSystem
         (lifetime as IClassicDesktopStyleApplicationLifetime)!.Shutdown();
         (lifetime as IClassicDesktopStyleApplicationLifetime)!.Shutdown();
         return false;
         return false;
     }
     }
-    
+
+    public void HandleActivatedWithFile(FileActivatedEventArgs fileActivatedEventArgs) { }
+
+    public void HandleActivatedWithUri(ProtocolActivatedEventArgs openUriEventArgs) { }
+
     private string?[] WrapSpaces(string[] args)
     private string?[] WrapSpaces(string[] args)
     {
     {
         string?[] wrappedArgs = new string?[args.Length];
         string?[] wrappedArgs = new string?[args.Length];

+ 28 - 4
src/PixiEditor/Initialization/ClassicDesktopEntry.cs

@@ -4,6 +4,7 @@ using System.Linq;
 using System.Text.RegularExpressions;
 using System.Text.RegularExpressions;
 using System.Threading;
 using System.Threading;
 using System.Threading.Tasks;
 using System.Threading.Tasks;
+using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Controls;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Controls.ApplicationLifetimes;
 using Avalonia.Threading;
 using Avalonia.Threading;
@@ -30,10 +31,28 @@ internal class ClassicDesktopEntry
     public ClassicDesktopEntry(IClassicDesktopStyleApplicationLifetime desktop)
     public ClassicDesktopEntry(IClassicDesktopStyleApplicationLifetime desktop)
     {
     {
         this.desktop = desktop;
         this.desktop = desktop;
+        IActivatableLifetime? activable =
+            (IActivatableLifetime?)App.Current.TryGetFeature(typeof(IActivatableLifetime));
+        if (activable != null)
+        {
+            activable.Activated += ActivableOnActivated;
+        }
         desktop.Startup += Start;
         desktop.Startup += Start;
         desktop.ShutdownRequested += ShutdownRequested;
         desktop.ShutdownRequested += ShutdownRequested;
     }
     }
 
 
+    private void ActivableOnActivated(object? sender, ActivatedEventArgs e)
+    {
+        if (e.Kind == ActivationKind.File && e is FileActivatedEventArgs fileActivatedEventArgs)
+        {
+            IOperatingSystem.Current.HandleActivatedWithFile(fileActivatedEventArgs);
+        }
+        else if(e.Kind == ActivationKind.OpenUri && e is ProtocolActivatedEventArgs openUriEventArgs)
+        {
+            IOperatingSystem.Current.HandleActivatedWithUri(openUriEventArgs);
+        }
+    }
+
     private void Start(object? sender, ControlledApplicationLifetimeStartupEventArgs e)
     private void Start(object? sender, ControlledApplicationLifetimeStartupEventArgs e)
     {
     {
         StartupArgs.Args = e.Args.ToList();
         StartupArgs.Args = e.Args.ToList();
@@ -136,17 +155,22 @@ internal class ClassicDesktopEntry
         return IOperatingSystem.Current.HandleNewInstance(dispatcher, OpenInExisting, desktop);
         return IOperatingSystem.Current.HandleNewInstance(dispatcher, OpenInExisting, desktop);
     }
     }
 
 
-    private void OpenInExisting(string passedArgsFile)
+    private void OpenInExisting(string passedArgs, bool isInline)
     {
     {
         if (desktop.MainWindow is MainWindow mainWindow)
         if (desktop.MainWindow is MainWindow mainWindow)
         {
         {
             mainWindow.BringIntoView();
             mainWindow.BringIntoView();
             List<string> args = new List<string>();
             List<string> args = new List<string>();
-            if (File.Exists(passedArgsFile))
+            if (isInline)
+            {
+                args = CommandLineHelpers.SplitCommandLine(passedArgs)
+                    .ToList();
+            }
+            else if (File.Exists(passedArgs))
             {
             {
-                args = CommandLineHelpers.SplitCommandLine(File.ReadAllText(passedArgsFile))
+                args = CommandLineHelpers.SplitCommandLine(File.ReadAllText(passedArgs))
                     .ToList();
                     .ToList();
-                File.Delete(passedArgsFile);
+                File.Delete(passedArgs);
             }
             }
 
 
             StartupArgs.Args = args;
             StartupArgs.Args = args;

+ 7 - 2
src/PixiEditor/ViewModels/SubViewModels/MiscViewModel.cs

@@ -21,14 +21,19 @@ internal class MiscViewModel : SubViewModel<ViewModelMain>
         MenuItemPath = "HELP/WEBSITE", MenuItemOrder = 1, AnalyticsTrack = true)]
         MenuItemPath = "HELP/WEBSITE", MenuItemOrder = 1, AnalyticsTrack = true)]
     [Command.Basic("PixiEditor.Links.OpenRepository", "https://github.com/PixiEditor/PixiEditor", "REPOSITORY", "OPEN_REPOSITORY", Icon = PixiPerfectIcons.Globe,
     [Command.Basic("PixiEditor.Links.OpenRepository", "https://github.com/PixiEditor/PixiEditor", "REPOSITORY", "OPEN_REPOSITORY", Icon = PixiPerfectIcons.Globe,
         MenuItemPath = "HELP/REPOSITORY", MenuItemOrder = 2, AnalyticsTrack = true)]
         MenuItemPath = "HELP/REPOSITORY", MenuItemOrder = 2, AnalyticsTrack = true)]
-    [Command.Basic("PixiEditor.Links.OpenLicense", "LICENSE", "LICENSE", "OPEN_LICENSE", Icon = PixiPerfectIcons.Globe,
+    [Command.Basic("PixiEditor.Links.OpenLicense", "{BaseDir}LICENSE", "LICENSE", "OPEN_LICENSE", Icon = PixiPerfectIcons.Folder,
         MenuItemPath = "HELP/LICENSE", MenuItemOrder = 3, AnalyticsTrack = true)]
         MenuItemPath = "HELP/LICENSE", MenuItemOrder = 3, AnalyticsTrack = true)]
-    [Command.Basic("PixiEditor.Links.OpenOtherLicenses", "Third Party Licenses", "THIRD_PARTY_LICENSES", "OPEN_THIRD_PARTY_LICENSES", Icon = PixiPerfectIcons.Globe,
+    [Command.Basic("PixiEditor.Links.OpenOtherLicenses", "{BaseDir}/Third Party Licenses", "THIRD_PARTY_LICENSES", "OPEN_THIRD_PARTY_LICENSES", Icon = PixiPerfectIcons.Folder,
         MenuItemPath = "HELP/THIRD_PARTY_LICENSES", MenuItemOrder = 4, AnalyticsTrack = true)]
         MenuItemPath = "HELP/THIRD_PARTY_LICENSES", MenuItemOrder = 4, AnalyticsTrack = true)]
     public static void OpenUri(string uri)
     public static void OpenUri(string uri)
     {
     {
         try
         try
         {
         {
+            if (uri.StartsWith("{BaseDir}"))
+            {
+                uri = uri.Replace("{BaseDir}", AppDomain.CurrentDomain.BaseDirectory);
+            }
+            
             IOperatingSystem.Current.OpenUri(uri);
             IOperatingSystem.Current.OpenUri(uri);
         }
         }
         catch (Exception e)
         catch (Exception e)

+ 2 - 1
src/PixiEditor/Views/MainWindow.axaml.cs

@@ -14,6 +14,7 @@ using PixiEditor.Helpers;
 using PixiEditor.Initialization;
 using PixiEditor.Initialization;
 using PixiEditor.Models.AnalyticsAPI;
 using PixiEditor.Models.AnalyticsAPI;
 using PixiEditor.Models.ExceptionHandling;
 using PixiEditor.Models.ExceptionHandling;
+using PixiEditor.Models.IO;
 using PixiEditor.Platform;
 using PixiEditor.Platform;
 using PixiEditor.ViewModels.SubViewModels;
 using PixiEditor.ViewModels.SubViewModels;
 using PixiEditor.Views.Rendering;
 using PixiEditor.Views.Rendering;
@@ -61,7 +62,7 @@ internal partial class MainWindow : Window
             .AddExtensionServices(extensionLoader)
             .AddExtensionServices(extensionLoader)
             .BuildServiceProvider();
             .BuildServiceProvider();
 
 
-        AsyncImageLoader.ImageLoader.AsyncImageLoader = new DiskCachedWebImageLoader();
+        AsyncImageLoader.ImageLoader.AsyncImageLoader = new DiskCachedWebImageLoader(Path.Combine(Paths.TempFilesPath, "ImageCache"));
 
 
         preferences = services.GetRequiredService<IPreferences>();
         preferences = services.GetRequiredService<IPreferences>();
         platform = services.GetRequiredService<IPlatform>();
         platform = services.GetRequiredService<IPlatform>();