Java 如何创建符号链接

Java 如何创建符号链接,java,windows,nio,symlink,Java,Windows,Nio,Symlink,在启用开发人员模式的Windows 10版本1803 build 17134.523上的NTFS卷上,我有一个文件myfile。我可以使用mklink创建指向此文件的符号链接。但是,如果我在java jre1.8.0_201上调用Files.createSymbolicLink,如果抛出: java.nio.file.FileSystemException: linkname: A required privilege is not held by the client. at sun

在启用开发人员模式的Windows 10版本1803 build 17134.523上的NTFS卷上,我有一个文件
myfile
。我可以使用
mklink
创建指向此文件的符号链接。但是,如果我在java jre
1.8.0_201
上调用
Files.createSymbolicLink
,如果抛出:

java.nio.file.FileSystemException: linkname: A required privilege is not held by the client.

    at sun.nio.fs.WindowsException.translateToIOException(Unknown Source)
    at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
    at sun.nio.fs.WindowsException.rethrowAsIOException(Unknown Source)
    at sun.nio.fs.WindowsFileSystemProvider.createSymbolicLink(Unknown Source)
    at java.nio.file.Files.createSymbolicLink(Unknown Source)
    at CreateLinks.main(CreateLinks.java:15)
在具有jre
1.8.0_191-8u191-b12-0ubuntu0.18.10.1-b12的Windows Linux子系统(WSL)上也可以正常工作


如果不进入WSL,我如何在windows上工作?这个异常到底在哪里抛出

创建符号链接需要secreateSymbolicClinkPrivilege,除非系统处于开发人员模式,并且调用WinAPI时使用标志
symbolic\u LINK\u flag\u ALLOW\u UNPRIVILEGED\u CREATE
(*)。CMD的
mklink
命令在Windows 10中使用此标志。显然Java JRE 1.8.0_201版没有

至于WSL,它继承了运行它的安全上下文。如果从具有secreateSymbolicClinkPrivilege的登录运行,WSL的最新版本将在drvfs(例如NTFS)卷上创建正常的Windows符号链接。否则,WSL使用自定义符号链接类型,该类型基于
IO_重分析_标记_LX_符号链接
(0xA000001D)重分析点,而不是正常的
IO_重分析_标记_符号链接
(0xA00000C)重分析点。您可以通过命令
fsutil reparsepoint query
查询重分析点的类型



(*)文件中说“[s]指定此标志,以允许在流程未提升时创建符号链接”。更准确地说,此标志允许在不使用secreateSymbolicClinkPrivilege的情况下创建符号链接,而secreateSymbolicClinkPrivilege仅与使用默认系统设置“提升”相关。就个人而言,我将此权限授予“已验证用户”组,在这种情况下,创建符号链接不需要提升到完全管理员权限。

创建符号链接需要secreateSymbolicClinkPrivilege,除非系统处于开发人员模式,并且使用标志
SYMBOLIC\u LINK\u flag\u ALLOW\u UNPRIVILEGED\u CREATE(*)调用WinAPI。CMD的
mklink
命令在Windows 10中使用此标志。显然Java JRE 1.8.0_201版没有

至于WSL,它继承了运行它的安全上下文。如果从具有secreateSymbolicClinkPrivilege的登录运行,WSL的最新版本将在drvfs(例如NTFS)卷上创建正常的Windows符号链接。否则,WSL使用自定义符号链接类型,该类型基于
IO_重分析_标记_LX_符号链接
(0xA000001D)重分析点,而不是正常的
IO_重分析_标记_符号链接
(0xA00000C)重分析点。您可以通过命令
fsutil reparsepoint query
查询重分析点的类型



(*)文件中说“[s]指定此标志,以允许在流程未提升时创建符号链接”。更准确地说,此标志允许在不使用secreateSymbolicClinkPrivilege的情况下创建符号链接,而secreateSymbolicClinkPrivilege仅与使用默认系统设置“提升”相关。就我个人而言,我将此权限授予“Authenticated Users”组,在这种情况下,创建符号链接不需要提升到完全管理员权限。

它与您的Java无关,只是与您的操作系统有关。请参阅以下连结:


关闭UAC的Win10-我必须设置本地策略>安全选项>用户帐户控制:在管理员批准模式下运行所有管理员=已禁用-否则-相同的文件系统异常:客户端不拥有所需的权限

它与您的Java无关,只是与您的操作系统有关。请参阅以下连结:


关闭UAC的Win10-我必须设置本地策略>安全选项>用户帐户控制:在管理员批准模式下运行所有管理员=已禁用-否则-相同的文件系统异常:客户端未持有所需的权限

您确定基础文件系统支持符号链接吗?@GhostCat确定,它是NTFS。在WSL上,创建符号链接完全按照预期工作。你是说Linux的windows子系统?在WSL上,我是说Linux的windows子系统,是的。@eryksun使用mklink直接工作,当从WSL在具有相同目标的相同文件上运行时,同样的代码也可以工作。您确定底层文件系统支持符号链接吗?@GhostCat确定,它是NTFS。在WSL上,创建符号链接的工作方式与预期完全相同。你是说Linux的windows子系统?在WSL中,我是说Linux的windows子系统,是的。@eryksun使用mklink可以直接工作,当从WSL在具有相同目标的相同文件上运行时,相同的代码也可以工作。它与Java相关,在进行系统调用时,它没有设置allow unpriviliged标志。它与Java相关,在进行系统调用时,它没有设置allow unpriviliged标志。我根据这个答案中的信息提交了一个功能请求,这是用Java修复并将用Java发布的13@Martijn,unprivileged create标志在以前版本的Windows中是无效参数。解决这个问题的直接方法是检查操作系统的内部版本号。我们还可以使用一个全局标志,该标志最初设置为允许使用unprivilegedcreate标志。如果调用作为无效参数失败,请在不使用unprivileged create标志的情况下重试。如果第二次调用成功,或者由于参数无效以外的错误而失败,则假定不支持新标志,并清除启用该标志的全局标志。我根据回答中的信息提交了一个功能请求,该问题已通过Java修复,并将通过Java发布13@Martijn,unprivileged create标志在以前版本的Windows中是无效参数。解决这个问题的直接方法是检查操作系统的内部版本号。我们还可以使用一个全局标志,该标志最初设置为允许使用unprivilegedcreate标志。如果调用作为无效参数失败,请在不使用unprivileged create标志的情况下重试。如果第二次调用成功,或者由于其他错误而失败