我想使用批处理文件从可移动驱动器中复制文件,而不考虑它得到的驱动器号。

到目前为止,不行。似乎没有任何可用的命令或第三方命令行工具可以根据卷标处理路径。

我尝试了FreeFileSync,但是它可以大量工作,并且在这里我需要精确的文件操作。另外,它不会删除,我需要从笔式驱动器上移走文件。

但是,引起我兴趣的是发出像这样的废话命令。

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%
  }
}

...但这很丑陋,并且不允许我做任何魔术,就像给两个Pendrive赋予相同的标签以使它们的行为相同一样。我知道这不是常见的情况,但是,为什么在可能有现成的解决方案的地方限制选择范围呢?

编辑:进度。我修改了子例程以将值返回为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返回一些类似空的值(不是空字符串;它无法通过if %%A==""检查)-因此IF EXIST \最终为true。如何消除这样的空结果?我在SET VOLUMEID=$FOO$之前尝试过FOR,但是无论如何它都会用一个空值覆盖它。

最后!这是一个概念证明,对于任何认为有用的人。
@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

我添加了$虚假值,以使其无法通过EXIST检查。
最后的SET VOLUMEID =%VOLUMEID ...行删除了结尾的反斜杠(由于某些原因,它算作两个字符),因此写为%MYDRIVE%\file*.*的路径看起来很合理。

最佳答案

这是一个子例程,它将通过名称将push编码到驱动器中,它带有一个参数-驱动器标签:

@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%
)

09-19 15:01