I’ve been working on a generic configuration utility for Web applications (more on this in a few days) that is meant to simplify the process of taking an ASP. Net application and configuring the typical, external OS and Web Server things you need to do set up a Web application: Creating a virtual, setting file permissions, setting up VS.NET Solution files, configure MSDE if necessary). I give out sample apps all the time and I'm tired of writing README.HTM files to describe how to open the application and solution and getting support calls <g>... Anyway...
This utility stores information in an XML Serialized format from an object that contains a number of paths like the directory for the virtual to create, any directories for permissions to be set etc. and in order to make this generic these paths need to be stored inside of the serialized file as Relative paths so it’s easy to transport this data around. The Path class has a number of useful path related functions like GetFullPath() (which does the opposite: Takes a relative path and converts it into a full path), but unfortunately no RelativePath function.
So I ended up writing one:
///
/// Returns a relative path string from a full path.
///
/// The path to convert. Can be either a file or a directory
/// The base path to truncate to and replace
///
/// Lower case string of the relative path. If path is a directory it's returned
/// without a backslash at the end.
///
/// Examples of returned values:
/// .\test.txt, ..\test.txt, ..\..\..\test.txt, ., ..
///
public static string GetRelativePath(string FullPath, string BasePath )
{
// *** Start by normalizing paths
FullPath = FullPath.ToLower();
BasePath = BasePath.ToLower();
if ( BasePath.EndsWith("\\") )
BasePath = BasePath.Substring(0,BasePath.Length-1);
if ( FullPath.EndsWith("\\") )
FullPath = FullPath.Substring(0,FullPath.Length-1);
// *** First check for full path
if ( FullPath.IndexOf(BasePath) > -1)
return FullPath.Replace(BasePath,".");
// *** Now parse backwards
string BackDirs = "";
string PartialPath = BasePath;
int Index = PartialPath.LastIndexOf("\\");
while (Index > 0)
{
// *** Strip path step string to last backslash
PartialPath = PartialPath.Substring(0,Index );
// *** Add another step backwards to our pass replacement
BackDirs = BackDirs + "..\\" ;
// *** Check for a matching path
if ( FullPath.IndexOf(PartialPath) > -1 )
{
if ( FullPath == PartialPath )
// *** Full Directory match and need to replace it all
return FullPath.Replace(PartialPath,
BackDirs.Substring(0,BackDirs.Length-1) );
else
// *** We're dealing with a file or a start path
return FullPath.Replace(PartialPath+
(FullPath == PartialPath ? "" : "\\"),BackDirs);
}
Index = PartialPath.LastIndexOf("\\",PartialPath.Length-1);
}
return FullPath;
}
I haven’t tested this through all the possible scenarios but it works well for both files and paths inside of a path tree.
As I was finishing this code, Mattias Sjoergen pointed out there’s an API call for this:
PathRelativePathTo
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/shlwapi/path/pathrelativepathto.asp
so you could use COM interop to talk to this as well if security of the app is not a concern. This function is a little more work though because you have to figure out first whether you are dealing with a path or a directory, while the code above works with either.
Relative paths are handy to have any time you are interested in storing configuration paths that need to travel across machines. If you let users pick filenames it's often a good idea to truncate those filenames into relative paths when you store them...
Other Posts you might also like