2009-08-19 2 views
6

Mi chiedo se esiste un modo universale per risolvere un percorso utilizzando una lettera di unità (come X:\foo\bar.txt) nel suo percorso UNC equivalente, che potrebbe essere uno dei seguenti:Risolvere la lettera di unità di Windows in un percorso (subst e rete)

  • X:\foo\bar.txt se X: è un'unità reale (cioè hard disk, chiavetta USB, ecc)
  • \\server\share\foo\bar.txt se X: è un'unità di rete montata su \\server\share
  • C:\xyz\foo\bar.txt se X: è il risultato di un SUBST comando di mappatura X: a C:\xyz

So che ci sono soluzioni parziali che sarà:

  1. risolvere un'unità di rete (si veda ad esempio question 556649 che si basa su WNetGetUniversalName)

  2. Risolvere il SUBST lettera di unità (vedere QueryDosDevice che funziona come previsto, ma non restituisce percorsi UNC per elementi quali unità locali o unità di rete).

Mi manca un modo semplice per implementare questa risoluzione di lettera di unità in Win32? O devo davvero pasticciare sia con lo WNetGetUniversalName sia con lo QueryDosDevice per ottenere ciò di cui ho bisogno?

risposta

2

Sì, è necessario risolvere la lettera di unità in modo indipendente.

WNetGetUniversalName() si avvicina, ma funziona solo per lettere di unità mappate a condivisioni UNC effettive, il che non è sempre il caso. Non esiste una singola funzione API che faccia tutto il lavoro per te.

6

Ecco un batch per tradurre lettere di unità in percorsi UNC o invertire percorsi substed. Non è garantito che funzioni comunque.

Esempio di utilizzo: 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, sì, andando nella direzione CMD è una soluzione ho rifiutato inizialmente. Stavo davvero cercando di trovare una API Win32 che avrebbe fatto il trucco. Ovviamente, la soluzione dovrebbe funzionare per le persone che cercano di fare la stessa cosa in un ambiente batch/scripting. Grazie mille per le tue idee; è stata l'occasione per me di (ri) scoprire alcuni trucchi CMD. –

+1

Questo script è fantastico. Un solo errore: non supporta gli spazi nel percorso di unità sostituito. Per risolvere il problema, modifica il primo ciclo for da: ... token = 1,2 ... a ... token = 1 * ... –

+0

@MrBungle: Grazie! Non sapevo che 'token = 1 *', indagheremo. Sei sicuro che non sia '1,2 *'? – Benoit