2

我想使用批处理文件从可移动驱动器上复制文件,而不管它获得的驱动器号。

到目前为止,没有去。似乎没有任何现成的命令或第 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%
  }
}

...但它很丑陋,并且不允许我做任何魔术,比如给两个笔式驱动器赋予相同的标签以使其行为相同。我知道这不是一种常见的情况,但是,嘿,为什么要限制一个人的选择,因为那里可能有现成的解决方案?


编辑:进展。我修改了子程序以将值作为 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 \最终为真。我如何消除这样的空结果..?我在 之前尝试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

我添加了要返回的 $ bogus 值以使 EXIST 检查失败。最后的 SET VOLUMEID=%VOLUMEID... 行删除了尾随的反斜杠(由于某种原因,它被视为两个字符),这样写成的路径%MYDRIVE%\file*.*看起来很正常。

4

2 回答 2

2

这是一个子程序,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%
)
于 2015-02-04T16:23:16.077 回答
0

这是最终的概念证明,对任何觉得它有用的人来说都是如此。调用 GetVolumeID 将 DRIVELETTER 变量设置为“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
于 2015-11-09T21:02:59.463 回答