2010-09-15 50 views
13

Tôi cần ánh xạ ổ đĩa mạng với một tập tin thực thi, nhưng không muốn chỉ định ký tự ổ đĩa.Lập bản đồ ổ đĩa mạng mà không cần mã hóa ổ đĩa trong một tập tin batch

Tệp lô được sử dụng như một phần của quy trình triển khai; Tôi gọi tập tin thực thi từ CruiseControl.Net, tập tin batch cần ánh xạ đường dẫn UNC yêu cầu thông tin xác thực để xác thực. Sau đó, tập tin batch gọi RoboCopy để triển khai trang web từ thư mục đầu ra đến đích (và loại trừ một số tệp và thư mục). Cuối cùng, lô xóa ổ đĩa mạng.

Vấn đề là điều này không thể mở rộng, sẽ tốt khi chỉ có một vài dự án nhưng hiện tại chúng tôi có 20 dự án sử dụng phương pháp này và sắp hết các ký tự ổ đĩa để lập bản đồ. Tôi không muốn sử dụng lại ký tự ổ đĩa khi chúng có thể va chạm - điều đó sẽ rất tệ.

Đây là một ví dụ về các tập tin thực thi:

@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 

và định dạng để có thể đọc:

@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 

Trả lời

28

Nếu bạn không có nhiều mạng chia sẻ kết nối simultaniously, bạn có thể làm net use * gán một thư ổ đĩa miễn phí cho bạn. Sau đó, bạn có thể sử dụng robocopy để truy cập chia sẻ qua đường dẫn UNC của nó và giải phóng bất kỳ chia sẻ được kết nối nào với net use * /delete.

Something như thế này:

@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:

Như tôi đã học được từ một số nghiên cứu, bạn chỉ có thể lập bản đồ tỷ lệ mà không gán một ký tự ổ đĩa. Sau đó nó được ánh xạ ẩn danh, chỉ bằng đường dẫn UNC từ xa của nó. Bằng cách này, bạn cũng có thể loại bỏ ánh xạ bằng cách chỉ định tên từ xa của nó.

này nên làm việc:

@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 
+0

Có là một cơ hội của nhiều mạng chia sẻ kết nối đồng thời, nếu không tôi chỉ có thể chỉ định Z: hoặc một chữ cái hardcoded cho mỗi dự án. sử dụng net */delete cũng sẽ giải phóng TẤT CẢ các lượt chia sẻ được kết nối và đó có thể là sự cố trên máy chủ –

+0

@Simon Martin: xem câu trả lời cập nhật của tôi. –

+0

đẹp hơn nhiều so với giải pháp của tôi :) –

2

Ok ... Đây có thể không phải quyến rũ nhưng đây là cách tôi đang làm điều này bây giờ; một phương pháp tiếp cận thử cơ bản. Hãy thử ánh xạ một ổ đĩa và nếu nó được sử dụng thì hãy goto bước tiếp theo. Tôi đã minh họa điều này chỉ với 2 lần thử, nhưng không khó để mở rộng nó đến 4, 10 hoặc nhiều ký tự ổ đĩa.

Có điều đó xúc phạm đến khả năng lập trình của tôi, tôi không thích việc lặp lại mã. Thật không may tôi không biết làm thế nào tôi có thể vượt qua con đường và thông tin vào tập tin thực thi như tôi không gọi nó là bản thân mình, CruiseControl.net gọi nó mà không có tham số.

@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 
10

tôi sử dụng này để cho NET chọn một ký tự ổ đĩa miễn phí, sau đó sử dụng NET để tìm ra những bức thư đó được giao:

net use * \\server\share 
for /f "tokens=2" %%i in ('net use ^| find "\\server\share"') do set netdrive=%%i 
echo %netdrive% has been mapped 
5

Một số có thể tìm thấy các tập tin thực thi sau hữu ích.

Nó không dựa vào các chương trình bên ngoài.

Tệp lô có chứa hàm :freedrive, tìm ký tự ổ đĩa tự do và trả về biến đó. Nó cũng phát hiện chính xác ổ đĩa quang không có phương tiện truyền thông như chiếm một ký tự ổ đĩa.

@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 
+0

Tôi thích cách tiếp cận này; không "kiểm tra xem những gì có sẵn và sử dụng nó" mà đúng hơn là "sử dụng nó và xem nó có hoạt động không". – Ben

0

phương pháp đơn giản nhất:

pushd "\\server\share\wwwroot\My Project" 
robocopy . x:\ *.* /E ...etc 
popd 

Pushd sẽ tự động ánh xạ một ổ đĩa mạng để một lá thư có sẵn, và popd sẽ loại bỏ nó. Chúng là các lệnh CMD nội bộ; sử dụng đường dẫn UNC yêu cầu bật tiện ích mở rộng. Ví dụ hàng loạt:

@echo off 
pushd %1 
    echo. --- Processing %1 as "%cd%" 
    echo. ... 
    rem do thing here 
    echo. Done. 
popd 

Lưu ý: trong triển khai này sử dụng đối số dòng lệnh, đường dẫn trên dòng lệnh phải được trích dẫn.

phiên Sample:

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> 
+0

Không có cách nào để xác định thông tin đăng nhập theo yêu cầu của OP. –

+0

@thomas: Chỉ có 2 trong số 6 câu trả lời ở đây hôm nay minh họa việc sử dụng thông tin đăng nhập, nhưng đây là câu trả lời duy nhất xứng đáng với một downvote? Sử dụng pushd thay vì vòng lặp For là trực tiếp và đơn giản hơn nhiều, cho phần của vấn đề mà nó giải quyết. –

+1

Các câu trả lời khác sử dụng lệnh 'net'. Mặc dù họ không minh họa cách sử dụng thông tin đăng nhập, nhưng ít nhất cũng có thể. –

0

@longneck, tôi sử dụng một cái gì đó như thế này:

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 

Điều này tránh các cuộc gọi thứ hai để NET đường ống thông qua tìm.

Bạn cũng có thể mở rộng tùy chọn này để thay vì gọi trực tiếp thiết lập netdrive, bạn làm điều đó trong một chương trình con. Điều này cho phép bạn kiểm tra hoặc xử lý lỗi nhiều hơn.

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 

Phân tích cú pháp chương trình con ở đây không hữu ích và chỉ minh họa khái niệm.

1

Một giải pháp khả thi là áp dụng pushd command cho đường dẫn UNC tồn tại chắc chắn, vì vậy một ký tự ổ đĩa tạm thời được tạo để trỏ đến đường dẫn đó. Thư mục hiện tại, cụ thể là thư mục gốc của ổ đĩa tạm thời, có thể được xác định để nhận được ký tự ổ đĩa. Cuối cùng, lệnh popd phải được sử dụng để xóa các ký tự ổ đĩa tạm thời:

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%`. 

Biến COMPUTERNAME và tỷ \\%COMPUTERNAME%\ADMIN$ nên tồn tại trên tất cả các hệ thống Windows hiện đại (NT-based).


Nếu bạn không muốn môi trường hiện tại để trở thành thậm chí tạm thời "ô nhiễm" bởi những nỗ lực của pushd để lấy được một ký tự ổ đĩa miễn phí, bạn có thể muốn sử dụng các phương pháp sau đây:

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%`. 
Các vấn đề liên quan