Сопоставление сетевого диска без жесткого кодирования буквы диска в пакетном файле
Мне нужно сопоставить сетевой диск с командным файлом, но не хочу указывать букву диска.
Пакетный файл используется как часть процесса развертывания; Я вызываю командный файл из CruiseControl.Net
, командный файл должен отображать путь UNC, для которого требуется аутентификация учетных данных. Затем командный файл вызывает RoboCopy
для развертывания веб-сайта из выходного каталога в пункт назначения (и исключает некоторые файлы и папки). Наконец пакет удаляет сетевой диск.
Проблема в том, что это не масштабируемо, это прекрасно, когда есть только несколько проектов, но у нас теперь есть 20 проектов, использующих этот подход, и на них не хватает букв дисков. Я не хочу повторно использовать буквы дисков, поскольку они могут столкнуться - что было бы плохо.
Это пример командного файла:
@echo off
net use x: \\192.168.0.1\Share\wwwroot\MyProject /user:mydomain\myuser MyP455w0rd
robocopy.exe "W:\wwwroot\MyProject" x:\ *.* /E /XO /XD "App_Data/Search" "*.svn" /XF "sitefinity.log" "Thumbs.db" /NDL /NC /NP
net use x: /delete
и отформатирован для удобства чтения:
@echo off
net use x: \\192.168.0.1\Share\wwwroot\MyProject
/user:mydomain\myuser MyP455w0rd
robocopy.exe "W:\wwwroot\MyProject" x:\ *.* /E /XO /XD
"App_Data/Search" "*.svn" /XF "sitefinity.log" "Thumbs.db" /NDL /NC /NP
net use x: /delete
Ответы
Ответ 1
Если у вас нет нескольких общих сетевых подключений, подключаемых одновременно, вы можете сделать net use *
присвоить вам букву бесплатного диска. Впоследствии вы можете использовать robocopy
для доступа к ресурсу через свой UNC-путь и освободить любой подключенный общий ресурс с помощью net use * /delete
.
Что-то вроде этого:
@echo off
net use * \\192.168.0.1\Share\wwwroot\MyProject /user:mydomain\myuser MyP455w0rd
robocopy.exe "W:\wwwroot\MyProject" "\\192.168.0.1\Share\wwwroot\MyProject" *.* /E /XO /XD "App_Data/Search" "*.svn" /XF "sitefinity.log" "Thumbs.db" /NDL /NC /NP
net use * /delete /yes
EDIT:
Как я узнал из некоторых исследований, вы можете просто сопоставить общий ресурс, не присваивая букву диска. Затем он отображается анонимно, только по его удаленному пути UNC. Таким образом вы также можете удалить отображение, указав только его удаленное имя.
Это должно работать:
@echo off
net use \\192.168.0.1\Share\wwwroot\MyProject /user:mydomain\myuser MyP455w0rd
robocopy.exe "W:\wwwroot\MyProject" "\\192.168.0.1\Share\wwwroot\MyProject" *.* /E /XO /XD "App_Data/Search" "*.svn" /XF "sitefinity.log" "Thumbs.db" /NDL /NC /NP
net use \\192.168.0.1\Share\wwwroot\MyProject /delete
Ответ 2
Я использую это, чтобы позволить NET выбрать бесплатную букву диска, а затем использовать NET, чтобы узнать, какую букву она назначила:
net use * \\server\share
for /f "tokens=2" %%i in ('net use ^| find "\\server\share"') do set netdrive=%%i
echo %netdrive% has been mapped
Ответ 3
Некоторые могут найти следующий пакетный файл.
Он не полагается на внешние программы.
Пакетный файл содержит функцию :freedrive
, которая находит бесплатную букву диска и возвращает ее в переменной. Он также правильно определяет оптические диски, у которых нет носителя, занимающего букву диска.
@echo off
setlocal
call :freedrive mydriveletter && goto :cont
echo ERROR: No free drive letter found.
goto :exit
:cont
echo Found drive letter: %mydriveletter%
goto :exit
rem Finds a free drive letter.
rem
rem Parameters:
rem %1 = Output variable name.
rem
rem Example:
rem call :freedrive mydriveletter && goto :cont
rem echo ERROR: No free drive letter found.
rem goto :EOF
rem :cont
rem echo Found drive letter: %mydriveletter%
:freedrive
setlocal EnableDelayedExpansion
set exitcode=0
set "output_var=%~1"
for %%i in (A,B,C,D,E,F,G,H,I,J,K,L,M,N,O,P,Q,R,S,T,U,V,W,X,Y,Z) do (
set "drive=%%i:"
rem If 'subst' fails, the drive letter is already in use.
rem This way we can even detect optical drives that have a drive
rem letter but no media in them, a case that goes undetected when
rem using 'if exist'.
subst !drive! %SystemDrive%\ >nul
if !errorlevel! == 0 (
subst !drive! /d >nul
goto :freedrive0
)
)
set exitcode=1
set drive=
:freedrive0
endlocal & set "%output_var%=%drive%" & exit /b %exitcode%
:exit
pause
Ответ 4
Хорошо... это может быть не гламурно, но вот как я это делаю сейчас; основной подход к подходу к попыткам. Попробуйте сопоставить диск, и если он используется, перейдите к следующему шагу. Я проиллюстрировал это всего двумя попытками, но не трудно расширить его до 4, 10 или более букв диска.
Да, это оскорбляет мою чувствительность к программированию, мне не нравится повторение кода. К сожалению, я не знаю, как я могу передать путь и учетные данные в пакетный файл, поскольку сам не называю его, CruiseControl.net называет его без параметров.
@echo off
:START
net use z: \\192.168.0.1\Share\wwwroot\MyProject /user:mydomain\myuser MyP455w0rd
if %ERRORLEVEL% ==2 goto Y
ROBOCOPY HERE
net use z: /delete
exit
:Y
net use y: \\192.168.0.1\Share\wwwroot\MyProject /user:mydomain\myuser MyP455w0rd
if %ERRORLEVEL% ==2 goto W
ROBOCOPY HERE
net use y: /delete
exit
:W
sleep 20
goto START
Ответ 5
Возможное решение - применить pushd
команду к определенному пути UNC, так что создается временная буква диска, указывающая на этот путь. Текущий каталог, а именно корень временного диска, можно определить, чтобы получить букву диска. Наконец, для удаления буквы временного диска необходимо использовать команду popd
:
pushd "\\%COMPUTERNAME%\ADMIN$"
rem /* Do stuff here with the root of the temporarily created drive
rem used as the current working directory... */
rem // Store the current drive in variable `DRIVE` for later use:
for /F "delims=:" %%D in ("%CD%") do set "DRIVE=%%D:"
popd
echo The next free drive letter is `%DRIVE%`.
Переменная COMPUTERNAME
и общий ресурс \\%COMPUTERNAME%\ADMIN$
должны существовать во всех современных (NT) системах Windows.
Если вы не хотите, чтобы текущая среда стала даже временно "загрязненной" попыткой pushd
получить букву бесплатного диска, вы можете использовать следующий подход:
for /F "delims=:" %%D in ('
pushd "\\%COMPUTERNAME%\ADMIN$" ^& ^
for %%Z in ^(.^) do popd
') do set "DRIVE=%%D:"
echo The next free drive letter is `%DRIVE%`.
Ответ 6
Самый простой способ:
pushd "\\server\share\wwwroot\My Project"
robocopy . x:\ *.* /E ...etc
popd
Pushd автоматически сопоставляет сетевой диск с доступной буквой и popd удалит его. Это внутренние команды CMD; использование UNC-путей требует активизации расширений. Пример:
@echo off
pushd %1
echo. --- Processing %1 as "%cd%"
echo. ...
rem do thing here
echo. Done.
popd
Примечание: в этой реализации с использованием аргумента командной строки необходимо указать путь в командной строке.
Пример сеанса:
E:\temp>.\demo-pushd.bat "\\server\share\wwwroot\My Project"
--- Processing "\\server\share\wwwroot\My Project" as "X:\wwwroot\My Project"
...
Done.
E:\temp> net use X:
The network connection could not be found.
More help is available by typing NET HELPMSG 2250.
E:\temp>
Ответ 7
@longneck, я использую что-то вроде этого:
for /f "tokens=2" %%i in ('net use * \\server\share') do (
if defined netdrive goto :cont
set netdrive=%%i
)
:cont
echo.%netdrive% has been mapped
pause
net use %netdrive% /d /y
pause
Это позволяет избежать второго вызова net piped через find.
Вы также можете развернуть это, чтобы вместо прямого вызова set netdrive вы делаете это в подпрограмме. Это позволяет выполнять дополнительную проверку или обработку ошибок.
for /f "tokens=2" %%i in ('net use * \\server\share') do (
if defined netdrive goto :cont
call :parse %%i
)
:parse
if ~%1==%1~ goto :eof
if Z:==%1 (
set netdrive=%1
)
goto :eof
:cont
echo.%netdrive% has been mapped
pause
net use %netdrive% /d /y
pause
Подпрограмма parse здесь не очень полезна и только иллюстрирует концепцию.