iis服务器助手广告
返回顶部
首页 > 资讯 > 精选 >.Net中的Junction Points怎么创建
  • 801
分享到

.Net中的Junction Points怎么创建

2023-07-02 10:07:14 801人浏览 独家记忆
摘要

本文小编为大家详细介绍“.net中的Junction Points怎么创建”,内容详细,步骤清晰,细节处理妥当,希望这篇“.Net中的Junction Points怎么创建”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢

本文小编为大家详细介绍“.net中的Junction Points怎么创建”,内容详细,步骤清晰,细节处理妥当,希望这篇“.Net中的Junction Points怎么创建”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

Junction Points是NTFS v5+的新特性,功能和我们所熟知的UNIX中的文件夹软链接类似(与windows中的文件夹快捷方式不同的是,它进行了路径重定向)。如在Vista中的C:\Documents and Settings 就是C:\Users的一个链接。然而,在Windows中并没有提供相关命令,只能编程通过api来实现。

创建Junction Point

// 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)// 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)

注:不能对文件创建Junction Points.

删除Junction Point

// 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")

判断Junction Point是否存在

// 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")

获取Junction Point所指向的实际地址

// 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

注:这个函数有问题,对系统的权限要求过高,如果对系统盘的一些文件夹链接访问往往会报异常,我把它改了一下,新的代码如下:

    /// <summary>    /// Provides access to NTFS junction points in .Net.    /// </summary>    public static class JunctionPoint    {        /// <summary>        /// The file or directory is not a reparse point.        /// </summary>        private const int ERROR_NOT_A_REPARSE_POINT = 4390;        /// <summary>        /// The reparse point attribute cannot be set because it conflicts with an existing attribute.        /// </summary>        private const int ERROR_REPARSE_ATTRIBUTE_CONFLICT = 4391;        /// <summary>        /// The data present in the reparse point buffer is invalid.        /// </summary>        private const int ERROR_INVALID_REPARSE_DATA = 4392;        /// <summary>        /// The tag present in the reparse point buffer is invalid.        /// </summary>        private const int ERROR_REPARSE_TAG_INVALID = 4393;        /// <summary>        /// There is a mismatch between the tag specified in the request and the tag present in the reparse point.        /// </summary>        private const int ERROR_REPARSE_TAG_MISMATCH = 4394;        /// <summary>        /// Command to set the reparse point data block.        /// </summary>        private const int FSCTL_SET_REPARSE_POINT = 0x000900A4;        /// <summary>        /// Command to get the reparse point data block.        /// </summary>        private const int FSCTL_GET_REPARSE_POINT = 0x000900A8;        /// <summary>        /// Command to delete the reparse point data base.        /// </summary>        private const int FSCTL_DELETE_REPARSE_POINT = 0x000900AC;        /// <summary>        /// Reparse point tag used to identify mount points and junction points.        /// </summary>        private const uint IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003;        /// <summary>        /// This prefix indicates to NTFS that the path is to be treated as a non-interpreted        /// path in the virtual file system.        /// </summary>        private const string NonInterpretedPathPrefix = @"\??\";        [Flags]        private enum EFileAccess : uint        {            GenericRead = 0x80000000,            GenericWrite = 0x40000000,            GenericExecute = 0x20000000,            GenericAll = 0x10000000,            GenericNone = 0x0,        }        [Flags]        private enum EFileShare : uint        {            None = 0x00000000,            Read = 0x00000001,            Write = 0x00000002,            Delete = 0x00000004,        }        private enum ECreationDisposition : uint        {            New = 1,            CreateAlways = 2,            OpenExisting = 3,            OpenAlways = 4,            TruncateExisting = 5,        }        [Flags]        private enum EFileAttributes : uint        {            Readonly = 0x00000001,            Hidden = 0x00000002,            System = 0x00000004,            Directory = 0x00000010,            ArcHive = 0x00000020,            Device = 0x00000040,            NORMal = 0x00000080,            Temporary = 0x00000100,            SparseFile = 0x00000200,            ReparsePoint = 0x00000400,            Compressed = 0x00000800,            Offline = 0x00001000,            NotContentIndexed = 0x00002000,            Encrypted = 0x00004000,            Write_Through = 0x80000000,            Overlapped = 0x40000000,            NoBuffering = 0x20000000,            RandoMaccess = 0x10000000,            SequentialScan = 0x08000000,            DeleteOnClose = 0x04000000,            BackupSemantics = 0x02000000,            PosixSemantics = 0x01000000,            OpenReparsePoint = 0x00200000,            OpenNoRecall = 0x00100000,            FirstPipeInstance = 0x00080000        }        [StructLayout(LayoutKind.Sequential)]        private struct REPARSE_DATA_BUFFER        {            /// <summary>            /// Reparse point tag. Must be a Microsoft reparse point tag.            /// </summary>            public uint ReparseTag;            /// <summary>            /// Size, in bytes, of the data after the Reserved member. This can be calculated by:            /// (4 * sizeof(ushort)) + SubstituteNameLength + PrintNameLength +             /// (namesAreNullTerminated ? 2 * sizeof(char) : 0);            /// </summary>            public ushort ReparseDataLength;            /// <summary>            /// Reserved; do not use.             /// </summary>            public ushort Reserved;            /// <summary>            /// Offset, in bytes, of the substitute name string in the PathBuffer array.            /// </summary>            public ushort SubstituteNameOffset;            /// <summary>            /// Length, in bytes, of the substitute name string. If this string is null-terminated,            /// SubstituteNameLength does not include space for the null character.            /// </summary>            public ushort SubstituteNameLength;            /// <summary>            /// Offset, in bytes, of the print name string in the PathBuffer array.            /// </summary>            public ushort PrintNameOffset;            /// <summary>            /// Length, in bytes, of the print name string. If this string is null-terminated,            /// PrintNameLength does not include space for the null character.             /// </summary>            public ushort PrintNameLength;            /// <summary>            /// A buffer containing the unicode-encoded path string. The path string contains            /// the substitute name string and print name string.            /// </summary>            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 0x3FF0)]            public byte[] PathBuffer;        }        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]        private static extern bool Deviceiocontrol(IntPtr hDevice, uint dwIoControlCode,            IntPtr InBuffer, int nInBufferSize,            IntPtr OutBuffer, int nOutBufferSize,            out int pBytesReturned, IntPtr lpOverlapped);        [DllImport("kernel32.dll", SetLastError = true)]        private static extern IntPtr CreateFile(            string lpFileName,            EFileAccess dwDesiredAccess,            EFileShare dwShareMode,            IntPtr lpSecurityAttributes,            ECreationDisposition dwCreationDisposition,            EFileAttributes dwFlagsAndAttributes,            IntPtr hTemplateFile);        /// <summary>        /// Creates a junction point from the specified directory to the specified target directory.        /// </summary>        /// <remarks>        /// Only works on NTFS.        /// </remarks>        /// <param name="junctionPoint">The junction point path</param>        /// <param name="targetDir">The target directory</param>        /// <param name="overwrite">If true overwrites an existing reparse point or empty directory</param>        /// <exception cref="IOException">Thrown when the junction point could not be created or when        /// an existing directory was found and <paramref name="overwrite" /> if false</exception>        public static void Create(string junctionPoint, string targetDir, bool overwrite)        {            targetDir = Path.GetFullPath(targetDir);            if (!Directory.Exists(targetDir))                throw new IOException("Target path does not exist or is not a directory.");            if (Directory.Exists(junctionPoint))            {                if (!overwrite)                    throw new IOException("Directory already exists and overwrite parameter is false.");            }            else            {                Directory.CreateDirectory(junctionPoint);            }            using (SafeFileHandle handle = OpenReparsePoint(junctionPoint, EFileAccess.GenericWrite))            {                byte[] targetDirBytes = Encoding.Unicode.GetBytes(NonInterpretedPathPrefix + Path.GetFullPath(targetDir));                REPARSE_DATA_BUFFER reparseDataBuffer = new REPARSE_DATA_BUFFER();                reparseDataBuffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;                reparseDataBuffer.ReparseDataLength = (ushort)(targetDirBytes.Length + 12);                reparseDataBuffer.SubstituteNameOffset = 0;                reparseDataBuffer.SubstituteNameLength = (ushort)targetDirBytes.Length;                reparseDataBuffer.PrintNameOffset = (ushort)(targetDirBytes.Length + 2);                reparseDataBuffer.PrintNameLength = 0;                reparseDataBuffer.PathBuffer = new byte[0x3ff0];                Array.Copy(targetDirBytes, reparseDataBuffer.PathBuffer, targetDirBytes.Length);                int inBufferSize = Marshal.SizeOf(reparseDataBuffer);                IntPtr inBuffer = Marshal.AllocHGlobal(inBufferSize);                try                {                    Marshal.StructureToPtr(reparseDataBuffer, inBuffer, false);                    int bytesReturned;                    bool result = DeviceIoControl(handle.DangerousGetHandle(), FSCTL_SET_REPARSE_POINT,                        inBuffer, targetDirBytes.Length + 20, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);                    if (!result)                        ThrowLastWin32Error("Unable to create junction point.");                }                finally                {                    Marshal.FreeHGlobal(inBuffer);                }            }        }        /// <summary>        /// Deletes a junction point at the specified source directory along with the directory itself.        /// Does nothing if the junction point does not exist.        /// </summary>        /// <remarks>        /// Only works on NTFS.        /// </remarks>        /// <param name="junctionPoint">The junction point path</param>        public static void Delete(string junctionPoint)        {            if (!Directory.Exists(junctionPoint))            {                if (File.Exists(junctionPoint))                    throw new IOException("Path is not a junction point.");                return;            }            using (SafeFileHandle handle = OpenReparsePoint(junctionPoint, EFileAccess.GenericWrite))            {                REPARSE_DATA_BUFFER reparseDataBuffer = new REPARSE_DATA_BUFFER();                reparseDataBuffer.ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;                reparseDataBuffer.ReparseDataLength = 0;                reparseDataBuffer.PathBuffer = new byte[0x3ff0];                int inBufferSize = Marshal.SizeOf(reparseDataBuffer);                IntPtr inBuffer = Marshal.AllocHGlobal(inBufferSize);                try                {                    Marshal.StructureToPtr(reparseDataBuffer, inBuffer, false);                    int bytesReturned;                    bool result = DeviceIoControl(handle.DangerousGetHandle(), FSCTL_DELETE_REPARSE_POINT,                        inBuffer, 8, IntPtr.Zero, 0, out bytesReturned, IntPtr.Zero);                    if (!result)                        ThrowLastWin32Error("Unable to delete junction point.");                }                finally                {                    Marshal.FreeHGlobal(inBuffer);                }                try                {                    Directory.Delete(junctionPoint);                }                catch (IOException ex)                {                    throw new IOException("Unable to delete junction point.", ex);                }            }        }        /// <summary>        /// Determines whether the specified path exists and refers to a junction point.        /// </summary>        /// <param name="path">The junction point path</param>        /// <returns>True if the specified path represents a junction point</returns>        /// <exception cref="IOException">Thrown if the specified path is invalid        /// or some other error occurs</exception>        public static bool Exists(string path)        {            if (!Directory.Exists(path))                return false;            using (SafeFileHandle handle = OpenReparsePoint(path, EFileAccess.GenericRead))            {                string target = InternalGetTarget(handle);                return target != null;            }        }        /// <summary>        /// Gets the target of the specified junction point.        /// </summary>        /// <remarks>        /// Only works on NTFS.        /// </remarks>        /// <param name="junctionPoint">The junction point path</param>        /// <returns>The target of the junction point</returns>        /// <exception cref="IOException">Thrown when the specified path does not        /// exist, is invalid, is not a junction point, or some other error occurs</exception>        public static string GetTarget(string junctionPoint)        {            using (SafeFileHandle handle = OpenReparsePoint(junctionPoint, EFileAccess.GenericNone))            {                string target = InternalGetTarget(handle);                if (target == null)                    throw new IOException("Path is not a junction point.");                return target;            }        }        private static string InternalGetTarget(SafeFileHandle handle)        {            int outBufferSize = Marshal.SizeOf(typeof(REPARSE_DATA_BUFFER));            IntPtr outBuffer = Marshal.AllocHGlobal(outBufferSize);            try            {                int bytesReturned;                bool result = DeviceIoControl(handle.DangerousGetHandle(), FSCTL_GET_REPARSE_POINT,                    IntPtr.Zero, 0, outBuffer, outBufferSize, out bytesReturned, IntPtr.Zero);                if (!result)                {                    int error = Marshal.GetLastWin32Error();                    if (error == ERROR_NOT_A_REPARSE_POINT)                        return null;                    ThrowLastWin32Error("Unable to get information about junction point.");                }                REPARSE_DATA_BUFFER reparseDataBuffer = (REPARSE_DATA_BUFFER)                    Marshal.PtrToStructure(outBuffer, typeof(REPARSE_DATA_BUFFER));                if (reparseDataBuffer.ReparseTag != IO_REPARSE_TAG_MOUNT_POINT)                    return null;                string targetDir = Encoding.Unicode.GetString(reparseDataBuffer.PathBuffer,                    reparseDataBuffer.SubstituteNameOffset, reparseDataBuffer.SubstituteNameLength);                if (targetDir.StartsWith(NonInterpretedPathPrefix))                    targetDir = targetDir.Substring(NonInterpretedPathPrefix.Length);                return targetDir;            }            finally            {                Marshal.FreeHGlobal(outBuffer);            }        }        private static SafeFileHandle OpenReparsePoint(string reparsePoint, EFileAccess acceSSMode)        {            SafeFileHandle reparsePointHandle = new SafeFileHandle(CreateFile(reparsePoint, accessMode,                EFileShare.Read | EFileShare.Write | EFileShare.Delete,                IntPtr.Zero, ECreationDisposition.OpenExisting,                EFileAttributes.BackupSemantics | EFileAttributes.OpenReparsePoint, IntPtr.Zero), true);            if (Marshal.GetLastWin32Error() != 0)                ThrowLastWin32Error("Unable to open reparse point.");            return reparsePointHandle;        }        private static void ThrowLastWin32Error(string message)        {            throw new IOException(message, Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error()));        }    }

读到这里,这篇“.Net中的Junction Points怎么创建”文章已经介绍完毕,想要掌握这篇文章的知识点还需要大家自己动手实践使用过才能领会,如果想了解更多相关内容的文章,欢迎关注编程网精选频道。

--结束END--

本文标题: .Net中的Junction Points怎么创建

本文链接: https://www.lsjlt.com/news/341199.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • .Net中的Junction Points怎么创建
    本文小编为大家详细介绍“.Net中的Junction Points怎么创建”,内容详细,步骤清晰,细节处理妥当,希望这篇“.Net中的Junction Points怎么创建”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢...
    99+
    2023-07-02
  • .NET MAUI项目中怎么创建超链接
    本篇内容介绍了“.NET MAUI项目中怎么创建超链接”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!.NET MAUI Previ...
    99+
    2023-06-29
  • 怎么创建一个.NET Core工程
    小编给大家分享一下怎么创建一个.NET Core工程,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!打开VS2019,点击“创建新项目”,选择“ASP.N...
    99+
    2023-06-29
  • .NET MAUI项目中创建超链接
    .NET MAUI Preview 13预览版中,.NET MAUI 支持带标签控件的格式化文本。 标签中的格式化文本 标签是显示带或不带文本环绕的文本的视图。使用格式化文本功能(现...
    99+
    2024-04-02
  • .NET中创建对象的几种方式和对比
    目录使用标准反射的 Invoke 方法使用 Activator.CreateInstance 使用 Microsoft.Extensions.DependencyInjection ...
    99+
    2024-04-02
  • dos中net如何创建管理员用户
    这篇文章给大家分享的是有关dos中net如何创建管理员用户的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。1、dos命令中net命令常用创建用户下面这段代码是用来创建一个管理员用户 代码:net user...
    99+
    2023-06-08
  • eclipse中的module怎么创建
    在Eclipse中创建模块的步骤如下:1. 打开Eclipse,点击菜单栏的“File” -> “New” -> “Project”...
    99+
    2023-08-26
    eclipse module
  • oracle创建监听Oracle Net Services配置失败怎么办
    小编给大家分享一下oracle创建监听Oracle Net Services配置失败怎么办,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!netca /silent /responseFil...
    99+
    2024-04-02
  • java中怎么创建list的map
    在Java中,可以通过以下两种方法来创建一个List的Map: 使用Map接口的实现类HashMap来创建一个Map,并在Map中...
    99+
    2024-03-13
    java
  • oracle 中怎么创建JOB
    今天就跟大家聊聊有关oracle 中怎么创建JOB,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1、创建JOB,可以指定固定的时间(对运行时间的管理...
    99+
    2024-04-02
  • C#.NET创建虚拟目录的方法详解
    目录使用背景配置创建使用结语使用背景 虚拟目录(virtual directory),计算机术语,每个 Internet服务可以从多个目录中发布。通过以通用命名约定 (UNC) 名、...
    99+
    2024-04-02
  • PHP中Cookie怎么创建
    这篇文章主要介绍PHP中Cookie怎么创建,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Cookie 是什么?cookie 常用于识别用户。cookie 是一种服务器留在用户计算机上的小文件。每当同一台计算机通过浏...
    99+
    2023-06-15
  • Ruby中怎么创建XML
    这期内容当中小编将会给大家带来有关Ruby中怎么创建XML,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。先安装ruby,再安装builderbuilder安装方法: gem install builder...
    99+
    2023-06-17
  • ilom中怎么创建snapshot
    ilom中怎么创建snapshot,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。配置Snapshot选项和生成路径->set /SP...
    99+
    2024-04-02
  • VB.NET中怎么创建WebService
    本篇文章给大家分享的是有关VB.NET中怎么创建WebService,小编觉得挺实用的,因此分享给大家学习,希望大家阅读完这篇文章后可以有所收获,话不多说,跟着小编一起来看看吧。VB.NET创建WebService.具体步骤如下: 新建一个...
    99+
    2023-06-17
  • java中threadgroup怎么创建
    java中threadgroup的创建方法:在java项目中能够通过构造方法直接创建threadgroup。用法说明创建threadgroup可以直接通过构造方法创建,构造方法有两个,一个是直接指定名字(threadgroup为main线程...
    99+
    2024-04-02
  • php中怎么创建ODBC
    本篇内容介绍了“php中怎么创建ODBC”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!ODBC 是一种应用...
    99+
    2024-04-02
  • 怎么创建一个创建MySQL数据库中的datetime类型
    今天小编给大家分享一下怎么创建一个创建MySQL数据库中的datetime类型的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。...
    99+
    2023-06-29
  • Python中的多进程怎么创建
    这篇“Python中的多进程怎么创建”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Python中的多进程怎么创建”文章吧。1...
    99+
    2023-07-02
  • C++中怎么创建新的进程
    在C++中创建新的进程有多种方法,以下是其中一种主要方法: 使用fork()和exec()函数: #include <io...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作