Преглед изворни кода

Merge pull request #542 from PixiEditor/args-parsing-fix

Fixed Command Line parsing wrongly paths with space
Krzysztof Krysiński пре 2 година
родитељ
комит
db611ef7b4

+ 25 - 2
src/PixiEditor/App.xaml.cs

@@ -2,6 +2,7 @@
 using System.Text.RegularExpressions;
 using System.Windows;
 using System.Windows.Media;
+using PixiEditor.Helpers.UI;
 using PixiEditor.Localization;
 using PixiEditor.Models.Controllers;
 using PixiEditor.Models.DataHolders;
@@ -69,6 +70,9 @@ internal partial class App : Application
 
         GC.KeepAlive(_mutex);
 
+        if (Current?.Dispatcher == null)
+            return true;
+
         if (isOwned)
         {
             var thread = new Thread(
@@ -86,7 +90,7 @@ internal partial class App : Application
                                     List<string> args = new List<string>();
                                     if (File.Exists(passedArgsFile))
                                     {
-                                        args = File.ReadAllText(passedArgsFile).Split(' ').ToList();
+                                        args = CommandLineHelpers.SplitCommandLine(File.ReadAllText(passedArgsFile)).ToList();
                                         File.Delete(passedArgsFile);
                                     }
                                     
@@ -107,7 +111,7 @@ internal partial class App : Application
         }
 
         // Notify other instance so it could bring itself to foreground.
-        File.WriteAllText(passedArgsFile, string.Join(' ', Environment.GetCommandLineArgs()));
+        File.WriteAllText(passedArgsFile, string.Join(' ', WrapSpaces(Environment.GetCommandLineArgs())));
         _eventWaitHandle.Set();
 
         // Terminate this instance.
@@ -115,6 +119,25 @@ internal partial class App : Application
         return false;
     }
 
+    private string?[] WrapSpaces(string[] args)
+    {
+        string?[] wrappedArgs = new string?[args.Length];
+        for (int i = 0; i < args.Length; i++)
+        {
+            string arg = args[i];
+            if (arg.Contains(' '))
+            {
+                wrappedArgs[i] = $"\"{arg}\"";
+            }
+            else
+            {
+                wrappedArgs[i] = arg;
+            }
+        }
+
+        return wrappedArgs;
+    }
+
     protected override void OnSessionEnding(SessionEndingCancelEventArgs e)
     {
         base.OnSessionEnding(e);

+ 47 - 0
src/PixiEditor/Helpers/UI/CommandLineHelpers.cs

@@ -0,0 +1,47 @@
+namespace PixiEditor.Helpers.UI;
+
+public static class CommandLineHelpers
+{
+    public static IEnumerable<string> SplitCommandLine(string commandLine)
+    {
+        bool inQuotes = false;
+
+        return commandLine.Split(
+            c =>
+            {
+                if (c == '\"')
+                    inQuotes = !inQuotes;
+
+                return !inQuotes && c == ' ';
+            })
+            .Select(arg => arg.Trim().TrimMatchingQuotes('\"'))
+            .Where(arg => !string.IsNullOrEmpty(arg));
+    }
+
+    public static IEnumerable<string> Split(
+        this string str,
+        Func<char, bool> controller)
+    {
+        int nextPiece = 0;
+
+        for (int c = 0; c < str.Length; c++)
+        {
+            if (controller(str[c]))
+            {
+                yield return str.Substring(nextPiece, c - nextPiece);
+                nextPiece = c + 1;
+            }
+        }
+
+        yield return str.Substring(nextPiece);
+    }
+
+    public static string TrimMatchingQuotes(this string input, char quote)
+    {
+        if ((input.Length >= 2) &&
+            (input[0] == quote) && (input[^1] == quote))
+            return input.Substring(1, input.Length - 2);
+
+        return input;
+    }
+}

+ 2 - 2
src/PixiEditor/Properties/AssemblyInfo.cs

@@ -50,5 +50,5 @@ using System.Windows;
 // You can specify all the values or you can default the Build and Revision Numbers
 // by using the '*' as shown below:
 // [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.1.0.0")]
-[assembly: AssemblyFileVersion("1.1.0.0")]
+[assembly: AssemblyVersion("1.1.1.0")]
+[assembly: AssemblyFileVersion("1.1.1.0")]