在 .NET 中,如何在 NTFS 中创建连接(而不是符号链接)?
我正在尝试创建一个 NTFS 连接。从 cmd 行,我可以使用 sysinternals 中的 junction.exe 工具。连接点的 DIR cmd 的输出如下所示:
Volume in drive C has no label.
Volume Serial Number is C8BC-2EBD
Directory of c:\users\cheeso\Documents
03/22/2009 09:45 PM <JUNCTION> My Music [\??\c:\users\cheeso\Music]
05/11/2007 05:42 PM <DIR> My Received Files
03/22/2009 09:46 PM <JUNCTION> my videos [\??\c:\users\cheeso\Videos]
我在某处读到连接点是符号链接的子集。
因此,我尝试使用 CreateSymbolicLink 创建一个连接点。当我这样做时,我实际上得到的是符号链接,而不是连接点。
09/09/2009 11:50 AM <SYMLINKD> newLink [.\]
还有 CreateHardLink。那里的文档说结点(又名“重新解析点”)是硬链接的子集。但我似乎无法让这个电话工作。它已完成,但没有创建硬链接或连接。
我正在使用 .NET/C#,导入如下所示:
[Interop.DllImport("kernel32.dll", EntryPoint="CreateSymbolicLinkW", CharSet=Interop.CharSet.Unicode)]
public static extern int CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, int dwFlags);
[Interop.DllImport("kernel32.dll", EntryPoint="CreateHardLinkW", CharSet=Interop.CharSet.Unicode)]
public static extern bool CreateHardLink(string lpFileName,
string lpExistingFileName,
IntPtr mustBeNull);
我做错了什么?
如何从 C# 中创建连接?
I'm trying to create an NTFS Junction. From the cmd line I can do this using the junction.exe tool from sysinternals. The output of a DIR cmd for a junction looks like this:
Volume in drive C has no label.
Volume Serial Number is C8BC-2EBD
Directory of c:\users\cheeso\Documents
03/22/2009 09:45 PM <JUNCTION> My Music [\??\c:\users\cheeso\Music]
05/11/2007 05:42 PM <DIR> My Received Files
03/22/2009 09:46 PM <JUNCTION> my videos [\??\c:\users\cheeso\Videos]
I read somewhere that Junctions are a subset of Symbolic Links.
So I tried using CreateSymbolicLink to create a Junction. When I do this, I actually get a Symlink, not a junction.
09/09/2009 11:50 AM <SYMLINKD> newLink [.\]
There is also CreateHardLink. The doc there says junctions (aka "Reparse Points") are a subset of hardlinks. but I can't seem to get this call to work. It completes but there is no hardlink or junction created.
I'm using .NET/C# and the imports look like this:
[Interop.DllImport("kernel32.dll", EntryPoint="CreateSymbolicLinkW", CharSet=Interop.CharSet.Unicode)]
public static extern int CreateSymbolicLink(string lpSymlinkFileName, string lpTargetFileName, int dwFlags);
[Interop.DllImport("kernel32.dll", EntryPoint="CreateHardLinkW", CharSet=Interop.CharSet.Unicode)]
public static extern bool CreateHardLink(string lpFileName,
string lpExistingFileName,
IntPtr mustBeNull);
What am I doing wrong?
How can I create a Junction from within C#?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
看起来可以,并且有人在 CodeProject 上创建了一个库,其中包含许多用 C# 构建的函数来处理连接点。
http://www.codeproject.com/KB/files/JunctionPointsNet.aspx
看起来他实际上是使用以下 DllImport 来完成它:
It looks like you can, and somebody's created a library on CodeProject that has a number of functions they've built in C# to work with Junction points.
http://www.codeproject.com/KB/files/JunctionPointsNet.aspx
It looks like he's actually using the following DllImport to accomplish it:
我已经简化/更新了 CodeProject 上 Jeff Brown 的 CreateJunction 代码,例如使用自动编组将结构传递给DeviceIoControl,而不必手动管理内存。我这样做只是为了创建一个连接,因为您可以使用 Directory.Delete() 进行删除,并且 .Net 的 GetAttributes 返回它是否具有重新分析点。
我还删除了目标目录存在检查,因为我发现能够创建到不存在或稍后将存在的文件夹的连接非常有用。 (不同的驱动器等)
我无法弄清楚的一件事是,添加到结构成员和 nInBufferSize DeviceIoControl 参数的字符串长度中的大小,它们似乎没有加起来等于 Marshal.SizeOf 返回值。
我在 VB.Net 中完成了此操作,因此我使用 IC#Code 的 CodeConverter 扩展将其转换为 C#:
以及源 VB.Net:
I have simplified/updated the CreateJunction code by Jeff Brown on CodeProject, e.g. using automatic marshalling to pass the structure along to DeviceIoControl instead of having to manually manage the memory. I've only done this for creating a junction, as you can delete with Directory.Delete() and .Net's GetAttributes returns whether it has a reparse point.
I've also removed the target dir exists check, as I find it useful to be able to create a junction to a folder that doesn't exist or will exist at some later point. (Different drive e.t.c.)
One thing I wasn't able to figure out, was the sizes added to the string length for the structure members and nInBufferSize DeviceIoControl parameter, they don't seem to add up to a Marshal.SizeOf return value.
I did this in VB.Net, so I used IC#Code's CodeConverter extension to convert it to C#:
And the source VB.Net:
该代码来自 http://www.codeproject.com/KB/files/JunctionPointsNet。 aspx 作为那些无法访问此链接或备份的快捷方式,以防原始页面关闭。
不要投票赞成这个答案,因为我不是这个代码的作者。
感谢原作者jeff.brown@代码项目。
The code is from http://www.codeproject.com/KB/files/JunctionPointsNet.aspx as a shortcut for those who can not reach this link or a backup in case the original page is down.
Do not vote up this answser, since I'm not author of this code.
Thanks to the original author jeff.brown@codeproject.
对于使用本文的任何人 https://www.codeproject .com/Articles/15633/Manipulated-NTFS-Junction-Points-in-NET
正如 @Walkman 和 @SqlRyan 答案中提到的,我在 Jeff Brown 的文章中添加了一个修复,用于在尝试创建自身的连接点时。
例如:
目录结构是:
应用程序文件夹
当前(连接点指向appFolder)
当尝试创建一个指向“当前”的连接点“当前”(带有覆盖标志)时,连接点会变得混乱,
解决方法如下:
For whoever uses this article https://www.codeproject.com/Articles/15633/Manipulating-NTFS-Junction-Points-in-NET
As mentioned in @Walkman and @SqlRyan answers, I added a fix to Jeff Brown's article for when trying to create a junction point to itself.
for example:
dir structure is:
appFolder
current (junction point points to appFolder)
When trying to create a junction point 'current' that points to 'current' (with the overwrite flag), the junction point gets messed up
Here's the fix: