如何在 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