如何在 Windows 路径中使用卷标?
How to use a volume label in a Windows path?
我想使用批处理文件从可移动驱动器上复制文件,而不考虑它获得的驱动器号。
到目前为止,没有去。似乎没有任何现成的命令或第 3 方命令行工具可以处理基于卷标的路径。
我试过FreeFileSync,但是大批量工作,我这里需要精确的文件操作。此外,它不会删除,我需要将文件从 pendrive 中移出。
然而,引起我兴趣的是发出一个无意义的命令,例如...
C:\> cd MYPENDRIVE:
...在默认错误消息中产生非常有趣的一点:
The filename, directory name, or volume label syntax is incorrect.
^^^^^^^^^^^^^^^^^^^
如果这条消息是可信的,那么这意味着有一些正确的语法可以将卷标放在那里。或者不存在?
注意:如果必须的话,我可以满足于编写一个小的 "getdriveletterforvolume" 工具,但我不想重新发明轮子。此外,在较长的批处理文件操作过程中,驱动器可能会被移除并替换为另一个驱动器,此时我需要停止操作,而不是在另一个驱动器上继续使用具有相同驱动器号的驱动器。
注意 2:使用 \\?\Volume{12345678.....} 是最后的手段,尽管它可以在某种程度上被驯服,以构建一个基本的批处理文件,例如...
SET PENDRIVE=\?\Volume{949a764e-a2f0-11e3-b710-6cf04975450b}
SET BACKUPDRIVE=\?\Volume{e79091c4-5c2a-11e3-86f9-806e6f6e6963}
if exist %PENDRIVE% {
if exist %BACKUPDRIVE% {
move %PENDRIVE%\*.* %BACKUPDRIVE%
}
}
...但它很丑陋而且不允许我做任何魔术,比如给两个 pendrives 相同的标签让它们表现相同。我知道这不是常见情况,但是嘿,为什么要在可能有现成解决方案的情况下限制一个人的选择?
编辑:进展。我将子例程修改为 return 一个值为 VOLUMEID:
CALL :GetVolumeID PENDRIVE
SET "PENDRIVE=%VOLUMEID%"
IF EXIST "%PENDRIVE%\" ECHO PENDRIVE is connected at %PENDRIVE%!
GOTO :eof
:GetVolumeID
FOR /F "skip=1" %%A in ('"wmic volume where label='%~1' get deviceid 2>/null"') do (
SET "VOLUMEID=%%A"
GOTO :eof
)
GOTO :eof
...但现在如果 pendrive 丢失,wmic
returns 一些类似空的值(不是空字符串;它未通过 if %%A==""
检查)- 和所以 IF EXIST \
最终成立。我如何消除这样的空结果..?我在 FOR
之前尝试了 SET VOLUMEID=$FOO$
,但无论如何它都会用空值覆盖它。
终于!这是一个概念证明,供任何认为有用的人使用。
@ECHO OFF
CALL :GetVolumeID BACKUPDRIVE
SET "BACKUPDRIVE=%VOLUMEID%"
CALL :GetVolumeID PENDRIVE
SET "PENDRIVE=%VOLUMEID%"
if exist %PENDRIVE%\ (
if exist %BACKUPDRIVE%\ (
echo Emptying the pendrive.
move %PENDRIVE%\*.* %BACKUPDRIVE%\pendrive\
)
)
GOTO :eof
:GetVolumeID
SET VOLUMEID=$$$
FOR /F "tokens=1,* delims==" %%A IN ('"wmic volume where label='%~1' get deviceid /value 2>nul"') DO IF NOT "%%~B"=="" SET "VOLUMEID=%%~B"
SET "VOLUMEID=%VOLUMEID:~0,-2%"
GOTO :eof
我添加了 $ 虚假值 returned 以失败 EXIST 检查。
最后的 SET VOLUMEID=%VOLUMEID... 行删除了结尾的反斜杠(出于某种原因,它算作两个字符),因此写为 %MYDRIVE%\file*.*
的路径看起来很正常。
这是一个子例程,它将 push
您通过其 name.It 接受一个参数 - 驱动器标签:
到一个驱动器
@echo off
:pushToLabel label
setlocal
for /f "skip=1 delims=:" %%A in ('"wmic logicaldisk where VolumeName='%~1' get name"') do (
set "drive=%%A:"
goto :break
)
:break
echo %drive%
endlocal && (
pushd %drive%
)
这是最后的概念验证,供任何认为有用的人使用。调用 GetVolumeID 将 DRIVELETTER 变量设置为 return,格式为 "F:"。
@ECHO OFF
CALL :GetVolumeID BACKUPDRIVE
SET "BACKUPDRIVE=%DRIVELETTER%"
CALL :GetVolumeID PENDRIVE
SET "PENDRIVE=%DRIVELETTER%"
if exist %PENDRIVE%\ (
if exist %BACKUPDRIVE%\ (
echo Emptying the pendrive.
move %PENDRIVE%\*.* %BACKUPDRIVE%\pendrive\
)
)
GOTO :eof
:GetVolumeID
SET DRIVELETTER=$$$
FOR /F "tokens=1,* delims==" %%A IN ('"wmic volume where label='%~1' get deviceid /value 2>nul"') DO IF NOT "%%~B"=="" SET "DRIVELETTER=%%~B"
SET "DRIVELETTER=%DRIVELETTER:~0,-2%"
GOTO :eof
我想使用批处理文件从可移动驱动器上复制文件,而不考虑它获得的驱动器号。
到目前为止,没有去。似乎没有任何现成的命令或第 3 方命令行工具可以处理基于卷标的路径。
我试过FreeFileSync,但是大批量工作,我这里需要精确的文件操作。此外,它不会删除,我需要将文件从 pendrive 中移出。
然而,引起我兴趣的是发出一个无意义的命令,例如...
C:\> cd MYPENDRIVE:
...在默认错误消息中产生非常有趣的一点:
The filename, directory name, or volume label syntax is incorrect.
^^^^^^^^^^^^^^^^^^^
如果这条消息是可信的,那么这意味着有一些正确的语法可以将卷标放在那里。或者不存在?
注意:如果必须的话,我可以满足于编写一个小的 "getdriveletterforvolume" 工具,但我不想重新发明轮子。此外,在较长的批处理文件操作过程中,驱动器可能会被移除并替换为另一个驱动器,此时我需要停止操作,而不是在另一个驱动器上继续使用具有相同驱动器号的驱动器。
注意 2:使用 \\?\Volume{12345678.....} 是最后的手段,尽管它可以在某种程度上被驯服,以构建一个基本的批处理文件,例如...
SET PENDRIVE=\?\Volume{949a764e-a2f0-11e3-b710-6cf04975450b}
SET BACKUPDRIVE=\?\Volume{e79091c4-5c2a-11e3-86f9-806e6f6e6963}
if exist %PENDRIVE% {
if exist %BACKUPDRIVE% {
move %PENDRIVE%\*.* %BACKUPDRIVE%
}
}
...但它很丑陋而且不允许我做任何魔术,比如给两个 pendrives 相同的标签让它们表现相同。我知道这不是常见情况,但是嘿,为什么要在可能有现成解决方案的情况下限制一个人的选择?
编辑:进展。我将子例程修改为 return 一个值为 VOLUMEID:
CALL :GetVolumeID PENDRIVE
SET "PENDRIVE=%VOLUMEID%"
IF EXIST "%PENDRIVE%\" ECHO PENDRIVE is connected at %PENDRIVE%!
GOTO :eof
:GetVolumeID
FOR /F "skip=1" %%A in ('"wmic volume where label='%~1' get deviceid 2>/null"') do (
SET "VOLUMEID=%%A"
GOTO :eof
)
GOTO :eof
...但现在如果 pendrive 丢失,wmic
returns 一些类似空的值(不是空字符串;它未通过 if %%A==""
检查)- 和所以 IF EXIST \
最终成立。我如何消除这样的空结果..?我在 FOR
之前尝试了 SET VOLUMEID=$FOO$
,但无论如何它都会用空值覆盖它。
终于!这是一个概念证明,供任何认为有用的人使用。
@ECHO OFF
CALL :GetVolumeID BACKUPDRIVE
SET "BACKUPDRIVE=%VOLUMEID%"
CALL :GetVolumeID PENDRIVE
SET "PENDRIVE=%VOLUMEID%"
if exist %PENDRIVE%\ (
if exist %BACKUPDRIVE%\ (
echo Emptying the pendrive.
move %PENDRIVE%\*.* %BACKUPDRIVE%\pendrive\
)
)
GOTO :eof
:GetVolumeID
SET VOLUMEID=$$$
FOR /F "tokens=1,* delims==" %%A IN ('"wmic volume where label='%~1' get deviceid /value 2>nul"') DO IF NOT "%%~B"=="" SET "VOLUMEID=%%~B"
SET "VOLUMEID=%VOLUMEID:~0,-2%"
GOTO :eof
我添加了 $ 虚假值 returned 以失败 EXIST 检查。
最后的 SET VOLUMEID=%VOLUMEID... 行删除了结尾的反斜杠(出于某种原因,它算作两个字符),因此写为 %MYDRIVE%\file*.*
的路径看起来很正常。
这是一个子例程,它将 push
您通过其 name.It 接受一个参数 - 驱动器标签:
@echo off
:pushToLabel label
setlocal
for /f "skip=1 delims=:" %%A in ('"wmic logicaldisk where VolumeName='%~1' get name"') do (
set "drive=%%A:"
goto :break
)
:break
echo %drive%
endlocal && (
pushd %drive%
)
这是最后的概念验证,供任何认为有用的人使用。调用 GetVolumeID 将 DRIVELETTER 变量设置为 return,格式为 "F:"。
@ECHO OFF
CALL :GetVolumeID BACKUPDRIVE
SET "BACKUPDRIVE=%DRIVELETTER%"
CALL :GetVolumeID PENDRIVE
SET "PENDRIVE=%DRIVELETTER%"
if exist %PENDRIVE%\ (
if exist %BACKUPDRIVE%\ (
echo Emptying the pendrive.
move %PENDRIVE%\*.* %BACKUPDRIVE%\pendrive\
)
)
GOTO :eof
:GetVolumeID
SET DRIVELETTER=$$$
FOR /F "tokens=1,* delims==" %%A IN ('"wmic volume where label='%~1' get deviceid /value 2>nul"') DO IF NOT "%%~B"=="" SET "DRIVELETTER=%%~B"
SET "DRIVELETTER=%DRIVELETTER:~0,-2%"
GOTO :eof