|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Announcements
Services
Chapters
Feature Zones
|
IntroductionJunction Points are a little known NTFS v5+ feature roughly equivalent to UNIX symbolic links. They are supported in Windows 2000 and onwards but cannot be accessed without special tools. In particular the .NET libraries does not include any functionality for creating or querying properties of Junction Points. This article provides sample code for creating Junction Points, testing their existence, querying their target and deleting them. I hope you find it of value in your own projects. BackgroundJunction Points are directories with a special attribute that indicates the target of the link. They is a special case of an NTFS feature known as a Reparse Point. A Reparse Point can roughly be thought of as a filter that is injected into the file system's name translation layer. The file system filter can transform how the name is parsed (hence the name) and redirect accesses to other resources. So Reparse Points can do much more than represent symbolic links but we're not going to worry about that today. Keep in mind this is an NTFS only feature. It will not work on other file systems. If your application relies on Junction Points in some way, you should be sure to provide alternate means of achieving the same end. Also, many applications are unaware of symbolic links. Usually that is okay but it can cause problems with tools that recursively copy or delete files because the Junction Point will simply appear to be a normal directory. For more background information about Junction Points or Reparse Points please consult the references at the end of this article. Using the codeThe source zip file includes two classes Creating a Junction PointUse the // Creates a Junction Point at
// C:\Foo\JunctionPoint that points to the directory C:\Bar.
// Fails if there is already a file,
// directory or Junction Point with the specified path.
JunctionPoint.Create(@"C:\Foo\JunctionPoint", @"C:\Bar",
false /*don't overwrite*/)
// Creates a Junction Point at C:\Foo\JunctionPoint that points to
// the directory C:\Bar.
// Replaces an existing Junction Point if found at the specified path.
JunctionPoint.Create(@"C:\Foo\JunctionPoint", @"C:\Bar", true /*overwrite*/)
Note: It is not possible to create Junction Points that refer to files. Deleting a Junction PointUse the // Delete a Junction Point at C:\Foo\JunctionPoint if it exists.
// Does nothing if there is no such Junction Point.
// Fails if the specified path refers to an existing file or
// directory rather than a Junction Point.
JunctionPoint.Delete(@"C:\Foo\JunctionPoint")
Determining existence of a Junction PointUse the // Returns true if there is a Junction Point at C:\Foo\JunctionPoint.
// Returns false if the specified path refers to an existing file
// or directory rather than a Junction Point
// or if it refers to the vacuum of space.
bool exists = JunctionPoint.Exists(@"C:\Foo\JunctionPoint")
Getting the target of a Junction PointUse the // Create a Junction Point for demonstration purposes whose target is C:\Bar.
JunctionPoint.Create(@"C:\Foo\JunctionPoint", @"C:\Bar", false)
// Returns the full path of the target of the Junction Point at
// C:\Foo\JunctionPoint.
// Fails if the specified path does not refer to a Junction Point.
string target = JunctionPoint.GetTarget(@"C:\Foo\JunctionPoint")
// target will be C:\Bar
Points of InterestI find it interesting that the .NET Framework's Junction Points make it possible to create cyclic references in the filesystem. So be careful with them. In particular, you should never try to recursively delete the target of a Junction Point! To avoid doing that ensure that the ReferencesThis project would not have been possible without the assistance of others in the community. I consulted the following references while implementing this functionality in .NET:
History
|
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||