如何使用命令行获取目录的网络路径
How to get network path of a directory using command line
假设我在 windows.
中有一个名为 Temp
的目录
当我右键单击它并打开属性,然后转到 Sharing
选项卡时,我看到了这个:
字段 Network Path
是 Not Shared
。
现在我单击 Share
和 select 与共享并单击确定。
字段 Network Path
现在有值:
有没有办法从命令行获取 Network Path
的值。
理想情况下,我正在寻找一个将目录路径作为输入的命令,例如C:\Temp
并输出 \S5XXXXXXN\Temp
如果目录是共享的或 Not Shared
如果目录不是共享的。
背景: 我有一个 NSIS 脚本来创建安装程序。安装过程结束时应该会吐出一个属性列表。输出所需的属性之一是目录的 Network Path
。在 NSIS 内部,我可用的是 C:\Temp
,我想在吐出之前将其转换为 \S5XXXXXXN\Temp
(如果可用)。
我尝试使用这个 https://nsis.sourceforge.io/Get_Universal_Name 但它不起作用。
DetailPrint "My directory is:"
# value of MYDIR is C:\Temp
DetailPrint $MYDIR
Push $MYDIR
Call get_universal_name
Pop $MYDIRNET
DetailPrint "My dir after call is: "
DetailPrint $MYDIRNET
# above also prints C:\Temp even though its shared and has value \S5XXXXXXN\Temp
更新:
下面@Anders 的回答很有魅力。
虽然返回的列表中有一个空白条目
。只是为了注意并在需要时添加必要的检查。
get_universal_name
调用 WNetGetUniversalName
并且此函数仅支持映射的驱动器号(net.exe use
样式)。 WNetGetConnection
似乎也有同样的限制。即使此限制不存在,它仍然无法工作,因为 a process elevated with UAC does not share the net connections with non-elevated processes.
换一种方式似乎可行,获取共享列表及其本地路径:
!include LogicLib.nsh
Section "Check shares"
System::Call 'NETAPI32::NetShareEnum(p0,i2,*p.r1,i-1,*i0r5,*i0,p0)i.r0'
${If} [=10=] = 0
Push
${DoWhile} <> 0
System::Call '*(p.r2,i,p,i,i,i,p.r3,p,&l.r4)'
IntPtrOp +
System::Call '*(&w${NSIS_MAX_STRLEN}.r2)'
System::Call '*(&w${NSIS_MAX_STRLEN}.r3)'
System::Call 'NETAPI32::NetServerGetInfo(p0,i100,*p.r4)' ; Get computer name
System::Call '*(i,w.s)'
System::Call 'NETAPI32::NetApiBufferFree(p)'
Pop
DetailPrint "=\$2"
; ${If} == "$MYDIR" ...TODO... ${EndIf}
IntOp - 1
${Loop}
System::Call 'NETAPI32::NetApiBufferFree(ps)'
${EndIf}
SectionEnd
假设我在 windows.
中有一个名为Temp
的目录
当我右键单击它并打开属性,然后转到 Sharing
选项卡时,我看到了这个:
字段 Network Path
是 Not Shared
。
现在我单击 Share
和 select 与共享并单击确定。
字段 Network Path
现在有值:
有没有办法从命令行获取 Network Path
的值。
理想情况下,我正在寻找一个将目录路径作为输入的命令,例如C:\Temp
并输出 \S5XXXXXXN\Temp
如果目录是共享的或 Not Shared
如果目录不是共享的。
背景: 我有一个 NSIS 脚本来创建安装程序。安装过程结束时应该会吐出一个属性列表。输出所需的属性之一是目录的 Network Path
。在 NSIS 内部,我可用的是 C:\Temp
,我想在吐出之前将其转换为 \S5XXXXXXN\Temp
(如果可用)。
我尝试使用这个 https://nsis.sourceforge.io/Get_Universal_Name 但它不起作用。
DetailPrint "My directory is:"
# value of MYDIR is C:\Temp
DetailPrint $MYDIR
Push $MYDIR
Call get_universal_name
Pop $MYDIRNET
DetailPrint "My dir after call is: "
DetailPrint $MYDIRNET
# above also prints C:\Temp even though its shared and has value \S5XXXXXXN\Temp
更新:
下面@Anders 的回答很有魅力。
虽然返回的列表中有一个空白条目 。只是为了注意并在需要时添加必要的检查。
get_universal_name
调用 WNetGetUniversalName
并且此函数仅支持映射的驱动器号(net.exe use
样式)。 WNetGetConnection
似乎也有同样的限制。即使此限制不存在,它仍然无法工作,因为 a process elevated with UAC does not share the net connections with non-elevated processes.
换一种方式似乎可行,获取共享列表及其本地路径:
!include LogicLib.nsh
Section "Check shares"
System::Call 'NETAPI32::NetShareEnum(p0,i2,*p.r1,i-1,*i0r5,*i0,p0)i.r0'
${If} [=10=] = 0
Push
${DoWhile} <> 0
System::Call '*(p.r2,i,p,i,i,i,p.r3,p,&l.r4)'
IntPtrOp +
System::Call '*(&w${NSIS_MAX_STRLEN}.r2)'
System::Call '*(&w${NSIS_MAX_STRLEN}.r3)'
System::Call 'NETAPI32::NetServerGetInfo(p0,i100,*p.r4)' ; Get computer name
System::Call '*(i,w.s)'
System::Call 'NETAPI32::NetApiBufferFree(p)'
Pop
DetailPrint "=\$2"
; ${If} == "$MYDIR" ...TODO... ${EndIf}
IntOp - 1
${Loop}
System::Call 'NETAPI32::NetApiBufferFree(ps)'
${EndIf}
SectionEnd