Risolvere lettera di unità di Windows in un percorso (subst e rete)
-
18-09-2019 - |
Domanda
Mi chiedo se c'è un modo universale di risolvere un percorso utilizzando una lettera di unità (come X:\foo\bar.txt
) nel suo equivalente percorso UNC, che potrebbe essere uno dei seguenti:
-
X:\foo\bar.txt
seX:
è un disco vero e proprio (cioè hard disk, chiavetta USB, ecc.) -
\\server\share\foo\bar.txt
seX:
è un'unità di rete montata su\\server\share
-
C:\xyz\foo\bar.txt
seX:
è il risultato di un comando di mappaturaSUBST
X:
aC:\xyz
So che ci sono soluzioni parziali che sarà:
-
Resolve un'unità di rete (si veda ad esempio domanda 556.649 che si basa su
WNetGetUniversalName
) -
Risolvere la lettera dell'unità
SUBST
(vediQueryDosDevice
che funziona come previsto, ma non restituisce percorsi UNC per cose come le unità locali o unità di rete).
Mi sto perdendo un modo semplice di attuazione della presente risoluzione lettera di unità in Win32? O devo davvero a pasticciare con sia WNetGetUniversalName
e QueryDosDevice
per ottenere quello che mi serve?
Soluzione
Si, si avrebbe bisogno di risolvere la lettera di unità in modo indipendente.
WNetGetUniversalName()
si avvicina, ma funziona solo per le lettere di unità mappate a condivisioni UNC effettivi, che non è sempre il caso. Non esiste un'unica funzione API che fa tutto il lavoro per voi.
Altri suggerimenti
Ecco un lotto di tradurre le lettere di unità a percorsi UNC o invertire percorsi substed. Non garantito funziona però.
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!