2009-08-19 10 views
6

Zastanawiam się, czy istnieje uniwersalny sposób rozwiązywania ścieżki przy użyciu litery dysku (takiej jak X:\foo\bar.txt) w jej równoważnej ścieżce UNC, która może być jedną z następujących:Rozpoznaj literę dysku systemu Windows na ścieżce (podrzędnej i sieci)

  • X:\foo\bar.txt jeśli X: to prawdziwy napęd (tj dysk twardy, pamięć USB, itd.)
  • \\server\share\foo\bar.txt jeśli X: jest dysk sieciowy zamontowany na \\server\share
  • C:\xyz\foo\bar.txt jeżeli X: jest wynikiem SUBST poleceń mapowanie X: do C:\xyz

Wiem, że istnieją rozwiązania częściowe, które będą:

  1. rozwiązać dysk sieciowy (patrz na przykład question 556649 która polega na WNetGetUniversalName)

  2. rozwiązać SUBST litera dysku (patrz QueryDosDevice, która działa zgodnie z oczekiwaniami, ale nie zwraca ścieżek UNC dla takich rzeczy, jak dyski lokalne lub dyski sieciowe).

Czy brakuje mi prostego sposobu implementacji tej rozdzielczości dysku w Win32? Czy naprawdę muszę zadziwić zarówno z WNetGetUniversalName i QueryDosDevice, aby uzyskać to, czego potrzebuję?

Odpowiedz

2

Tak, trzeba osobno rozwiązać literę dysku.

WNetGetUniversalName() jest blisko, ale działa tylko w przypadku liter dysków mapowanych na rzeczywiste udziały UNC, co nie zawsze ma miejsce. Nie ma jednej funkcji API, która wykonuje całą pracę za Ciebie.

6

Oto partia do tłumaczenia liter dysków na ścieżki UNC lub odwrotne ścieżki podrzędne. Nie gwarantowane, że to działa.

Przykład zastosowania: script.cmd echo Z: Y: W:

@echo off 
:: u is a variable containing all arguments of the current command line 
set u=%* 

:: enabledelayedexpansion: exclamation marks behave like percentage signs and enable 
:: setting variables inside a loop 
setlocal enabledelayedexpansion 

:: parsing result of command subst 
:: format: I: => C:\foo\bar 
:: variable %G will contain I: and variable H will contain C:\foo\bar 
for /f "tokens=1* delims==> " %%G IN ('subst') do (
set drive=%%G 
:: removing extra space 
set drive=!drive:~0,2! 
:: expanding H to a short path in order not to break the resulting command line 
set subst=%%~sfH 
:: replacing command line. 
call set u=%%u:!drive!=!subst!%% 
) 

:: parsing result of command net use | findstr \\ ; this command is not easily tokenized because not always well-formatted 
:: testing whether token 2 is a drive letter or a network path. 
for /f "tokens=1,2,3 delims= " %%G IN ('net use ^| findstr \\') do (
set tok2=%%H 
if "!tok2:~0,2!" == "\\" (
    set drive=%%G 
    set subst=%%H 
) else (
    set drive=%%H 
    set subst=%%I 
) 
:: replacing command line. 
call set u=%%u:!drive!=!subst!%% 
) 

call !u! 
+0

ah, tak, przechodząc drogę CMD jest rozwiązaniem Odrzuciłem początkowo. Naprawdę starałem się znaleźć Win32 API, który mógłby zrobić lewy. Oczywiście, twoje rozwiązanie powinno działać dla osób próbujących zrobić to samo w środowisku wsadowym/skryptowym. Wielkie dzięki za twoje pomysły; to była okazja, aby (ponownie) odkryć niektóre sztuczki CMD. –

+1

Ten skrypt jest niesamowity. Tylko jeden błąd - nie obsługuje spacji w podstawionej ścieżce dysku. Aby naprawić, zmień pierwszą pętlę for z: ... tokeny = 1,2 ... na ... tokeny = 1 * ... –

+0

@MrBungle: Dzięki! Nie wiedziałem o "tokenach = 1 *", zbada. Jesteś pewien, że to nie jest "1,2 *"? – Benoit

Powiązane problemy