1 #region Copyright (c) 2002-2003, James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole, Philip A. Craig
2 /************************************************************************************
4 ' Copyright 2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
5 ' Copyright 2000-2002 Philip A. Craig
7 ' This software is provided 'as-is', without any express or implied warranty. In no
8 ' event will the authors be held liable for any damages arising from the use of this
11 ' Permission is granted to anyone to use this software for any purpose, including
12 ' commercial applications, and to alter it and redistribute it freely, subject to the
13 ' following restrictions:
15 ' 1. The origin of this software must not be misrepresented; you must not claim that
16 ' you wrote the original software. If you use this software in a product, an
17 ' acknowledgment (see the following) in the product documentation is required.
19 ' Portions Copyright 2002-2003 James W. Newkirk, Michael C. Two, Alexei A. Vorontsov, Charlie Poole
20 ' or Copyright 2000-2002 Philip A. Craig
22 ' 2. Altered source versions must be plainly marked as such, and must not be
23 ' misrepresented as being the original software.
25 ' 3. This notice may not be removed or altered from any source distribution.
27 '***********************************************************************************/
33 using System.Runtime.InteropServices;
38 /// Static methods for manipulating project paths, including both directories
39 /// and files. Some synonyms for System.Path methods are included as well.
41 public class ProjectPath
43 public const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;
44 public const uint FILE_ATTRIBUTE_NORMAL = 0x00000080;
45 public const int MAX_PATH = 256;
47 #region Public methods
49 public static bool IsAssemblyFileType( string path )
51 string extension = Path.GetExtension( path );
52 return extension == ".dll" || extension == ".exe";
56 /// Returns the relative path from a base directory to another
57 /// directory or file.
59 public static string RelativePath( string from, string to )
61 from = Canonicalize( from );
62 to = Canonicalize( to );
64 // Second argument to PathRelativeTo must be absolute
65 if ( !Path.IsPathRooted( to ) )
68 StringBuilder sb = new StringBuilder( MAX_PATH );
70 // Return null if call fails
71 if ( !PathRelativePathTo( sb, from, FILE_ATTRIBUTE_DIRECTORY, to, FILE_ATTRIBUTE_DIRECTORY ) )
74 // Remove initial .\ from path if present
75 if ( sb.Length >=2 && sb[0] == '.' && sb[1] == '\\' )
85 /// Return the canonical form of a path.
86 public static string Canonicalize( string path )
88 StringBuilder sb = new StringBuilder( MAX_PATH );
89 if ( !PathCanonicalize( sb, path ) )
90 throw new ArgumentException( string.Format( "Invalid path passed to PathCanonicalize: {0}", path ) );
96 /// True if the two paths are the same. However, two paths
97 /// to the same file or directory using different network
98 /// shares or drive letters are not treated as equal.
100 public static bool SamePath( string path1, string path2 )
102 return Canonicalize(path1).ToLower() == Canonicalize(path2).ToLower();
106 /// True if the two paths are the same or if the second is
107 /// directly or indirectly under the first. Note that paths
108 /// using different network shares or drive letters are
109 /// considered unrelated, even if they end up referencing
110 /// the same subtrees in the file system.
112 public static bool SamePathOrUnder( string path1, string path2 )
114 path1 = Canonicalize( path1 );
115 path2 = Canonicalize( path2 );
117 int length1 = path1.Length;
118 int length2 = path2.Length;
120 // if path1 is longer, then path2 can't be under it
121 if ( length1 > length2 )
124 // if lengths are the same, check for equality
125 if ( length1 == length2 )
126 return path1.ToLower() == path2.ToLower();
128 // path 2 is longer than path 1: see if initial parts match
129 if ( path1.ToLower() != path2.Substring( 0, length1 ).ToLower() )
132 // must match through or up to a directory separator boundary
133 return path2[length1-1] == Path.DirectorySeparatorChar ||
134 path2[length1] == Path.DirectorySeparatorChar;
139 #region Shlwapi functions used internally
141 [DllImport("shlwapi.dll")]
142 private static extern bool PathRelativePathTo(
143 StringBuilder result,
149 [DllImport("shlwapi.dll")]
150 private static extern bool PathCanonicalize(
151 StringBuilder result,
154 [DllImport("shlwapi.dll")]
155 private static extern int PathCommonPrefix(
158 StringBuilder result );