/// <summary>
        /// Command line string --> string[]
        /// Utilizes CommandLineToArgvW win32 API if preserveQuotes = false
        /// </summary>
        /// <returns></returns>
        public static string[] CommandLineToArgs(string commandLine, bool preserveQuotes = true, bool removeFirstArgAsExePath = true)
        {
            if (preserveQuotes)
            {
                // Custom parsing to preserve quotes. Otherwise CommandLineToArgvW will remove them, and it will require quote escaping
                string[] ret = GetArgumentsPreserveQuotes(commandLine);

                if (removeFirstArgAsExePath)
                {
                    return(RemoveThisExeArg(ret));
                }
                else
                {
                    return(ret);
                }
            }
            else
            {
                // Win32 API removes the quotes

                //
                // From / based on: stackoverflow.com/a/749653
                //

                int argCount;
                var argv = APIs.CommandLineToArgvW(commandLine, out argCount);
                if (argv == IntPtr.Zero)
                {
                    //throw new System.ComponentModel.Win32Exception();
                    return(new string[0]);
                }

                try
                {
                    var args = new string[argCount];
                    for (var i = 0; i < args.Length; i++)
                    {
                        var p = Marshal.ReadIntPtr(argv, i * IntPtr.Size);
                        args[i] = Marshal.PtrToStringUni(p);
                    }

                    if (removeFirstArgAsExePath)
                    {
                        return(RemoveThisExeArg(args));
                    }
                    else
                    {
                        return(args);
                    }
                }
                finally
                {
                    Marshal.FreeHGlobal(argv);
                }
            }
        }