问题描述
假设我在 Windows 中有一个名为 Temp
的目录。
当我右键单击它并打开属性并转到 Sharing
选项卡时,我看到了:
字段 Network Path
是 Not Shared
。
现在我点击 Share
并选择共享并点击确定。
字段 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 下面的回答很有魅力。
返回的列表中有一个带有空白 $3
的条目。只是为了了解并在需要时添加必要的检查。
解决方法
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} $0 = 0
Push $1
${DoWhile} $5 <> 0
System::Call '*$1(p.r2,i,p,p.r3,&l.r4)'
IntPtrOp $1 $1 + $4
System::Call '*$2(&w${NSIS_MAX_STRLEN}.r2)'
System::Call '*$3(&w${NSIS_MAX_STRLEN}.r3)'
System::Call 'NETAPI32::NetServerGetInfo(p0,i100,*p.r4)' ; Get computer name
System::Call '*$4(i,w.s)'
System::Call 'NETAPI32::NetApiBufferFree(p$4)'
Pop $4
DetailPrint "$3=\\$4\$2"
; ${If} $3 == "$MYDIR" ...TODO... ${EndIf}
IntOp $5 $5 - 1
${Loop}
System::Call 'NETAPI32::NetApiBufferFree(ps)'
${EndIf}
SectionEnd