ネットワークドライブをバッチファイルにマップする必要がありますが、ドライブ文字を指定したくありません。
バッチファイルは、展開プロセスの一部として使用されます。 CruiseControl.Net
からバッチファイルを呼び出します。バッチファイルは、認証に資格情報を必要とするUNCパスをマップする必要があります。次に、バッチファイルはRoboCopy
を呼び出して、Webサイトを出力ディレクトリから宛先に展開します(一部のファイルとフォルダーは除外されます)。最後に、バッチはネットワークドライブを削除します。
問題は、これがスケーラブルではないことです。プロジェクトが少数の場合は問題ありませんが、このアプローチを使用してプロジェクトが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
複数のネットワーク共有を同時に接続していない場合は、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
編集:
いくつかの調査から学んだように、ドライブ文字を割り当てずに、単に共有をマップできます。その後、リモート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
これを使用して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
一部のユーザーは、次のバッチファイルが役立つ場合があります。
外部プログラムには依存しません。
バッチファイルには関数: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
OK ...これは魅力的ではないかもしれませんが、これは私が今これをやっている方法です。基本的なトライキャッチアプローチ。ドライブをマップしてみてください。ドライブが使用中の場合は、次のステップに進んでください。これを2回の試行で説明しましたが、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
考えられる解決策は、確実に存在するUNCパスに pushd
コマンド を適用することです。そのため、そのパスを指す一時的なドライブ文字が作成されます。現在のディレクトリ、つまり一時ドライブのルートは、ドライブ文字を取得するために決定できます。最後に、 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%`.
最も簡単な方法:
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>
@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
これにより、findを介してパイプされるnetへの2番目の呼び出しが回避されます。
これを拡張して、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
ここでの構文解析サブルーチンはそれほど有用ではなく、概念を説明するだけです。