コード例 #1
0
ファイル: APath.cs プロジェクト: alexfordc/Au
        /// <summary>
        /// Same as <see cref="Normalize"/>, but skips full-path checking.
        /// s should be full path. If not full and not null/"", combines with current directory.
        /// </summary>
        internal static string Normalize_(string s, PNFlags flags = 0, bool noExpandEV = false)
        {
            if (!s.NE())
            {
                if (!noExpandEV)
                {
                    s = ExpandEnvVar(s);
                }
                Debug.Assert(!IsShellPath_(s) && !IsUrl(s));

                if (_EndsWithDriveWithoutSep(s))
                {
                    s += "\\";                                             //API would append current directory
                }
                //note: although slower, call GetFullPathName always, not just when contains @"..\" etc.
                //	Because it does many things (see Normalize doc), not all documented.
                //	We still ~2 times faster than Path.GetFullPath.
                for (int na = 300; ;)
                {
                    var b  = Util.AMemoryArray.Char_(ref na);
                    int nr = Api.GetFullPathName(s, na, b, null);
                    if (nr > na)
                    {
                        na = nr;
                    }
                    else
                    {
                        if (nr > 0)
                        {
                            s = b.ToString(nr);
                        }
                        break;
                    }
                }

                if (0 == (flags & PNFlags.DontExpandDosPath) && IsPossiblyDos_(s))
                {
                    s = ExpandDosPath_(s);
                }

                if (0 == (flags & PNFlags.DontRemoveEndSeparator))
                {
                    s = _AddRemoveSep(s);
                }
                else if (_EndsWithDriveWithoutSep(s))
                {
                    s += "\\";
                }

                if (0 == (flags & PNFlags.DontPrefixLongPath))
                {
                    s = PrefixLongPathIfNeed(s);
                }
            }
            return(s);
        }
コード例 #2
0
ファイル: APath.cs プロジェクト: alexfordc/Au
        /// <summary>
        /// Makes normal full path from path that can contain special substrings etc.
        /// </summary>
        /// <param name="path">Any path.</param>
        /// <param name="defaultParentDirectory">If path is not full path, combine it with defaultParentDirectory to make full path.</param>
        /// <param name="flags"></param>
        /// <exception cref="ArgumentException">path is not full path, and <i>defaultParentDirectory</i> is not used or does not make it full path.</exception>
        /// <remarks>
        /// The sequence of actions:
        /// 1. If path starts with '%' character, expands environment variables and special folder names. See <see cref="ExpandEnvVar"/>.
        /// 2. If path is not full path but looks like URL, and used flag CanBeUrl, returns path.
        /// 3. If path is not full path, and defaultParentDirectory is not null/"", combines path with ExpandEnvVar(defaultParentDirectory).
        /// 4. If path is not full path, throws exception.
        /// 5. Calls API <msdn>GetFullPathName</msdn>. It replaces <c>'/'</c> with <c>'\\'</c>, replaces multiple <c>'\\'</c> with single (where need), processes <c>@"\.."</c> etc, trims spaces, etc.
        /// 6. If no flag DontExpandDosPath, if path looks like a short DOS path version (contains <c>'~'</c> etc), calls API <msdn>GetLongPathName</msdn>. It converts short DOS path to normal path, if possible, for example <c>@"c:\progra~1"</c> to <c>@"c:\program files"</c>. It is slow. It converts path only if the file exists.
        /// 7. If no flag DontRemoveEndSeparator, removes <c>'\\'</c> character at the end, unless it is like <c>@"C:\"</c>.
        /// 8. Appends <c>'\\'</c> character if ends with a drive name (eg <c>"C:"</c> -> <c>@"C:\"</c>).
        /// 9. If no flag DontPrefixLongPath, calls <see cref="PrefixLongPathIfNeed"/>, which adds <c>@"\\?\"</c> etc prefix if path is very long.
        ///
        /// Similar to <see cref="Path.GetFullPath"/>. Main differences: this function expands environment variables, does not support relative paths, supports <c>@"\\?\very long path"</c>, trims <c>'\\'</c> at the end if need, does not throw exceptions when it thinks that path is invalid (except when path is not full).
        /// </remarks>
        public static string Normalize(string path, string defaultParentDirectory = null, PNFlags flags = 0)
        {
            path = ExpandEnvVar(path);
            if (!IsFullPath(path))              //note: not EEV
            {
                if (0 != (flags & PNFlags.CanBeUrlOrShell))
                {
                    if (IsShellPath_(path) || IsUrl(path))
                    {
                        return(path);
                    }
                }
                if (defaultParentDirectory.NE())
                {
                    goto ge;
                }
                path = Combine_(ExpandEnvVar(defaultParentDirectory), path);
                if (!IsFullPath(path))
                {
                    goto ge;
                }
            }

            return(Normalize_(path, flags, true));

ge:
            throw new ArgumentException($"Not full path: '{path}'.");
        }