2009-08-19 14 views
6

Me pregunto si existe una forma universal de resolver una ruta usando una letra de unidad (como X:\foo\bar.txt) en su ruta UNC equivalente, que podría ser una de las siguientes:Resolver letra de unidad de Windows a una ruta (subst y red)

  • X:\foo\bar.txt si X: es una unidad real (es decir, disco duro, memoria USB, etc.)
  • \\server\share\foo\bar.txt si X: es una unidad de red montada en \\server\share
  • C:\xyz\foo\bar.txtX: si es el resultado de un SUBST comando de asignación de X: a C:\xyz

Sé que hay soluciones parciales que serán:

  1. resolver una unidad de red (véase, por ejemplo question 556649 que se basa en WNetGetUniversalName)

  2. resolver el SUBST letra de unidad (consulte QueryDosDevice que funciona como se esperaba, pero no devuelve las rutas de acceso UNC para elementos tales como unidades locales o unidades de red).

¿Falta alguna forma directa de implementar esta resolución de letra de unidad en Win32? ¿O realmente tengo que meterme tanto con WNetGetUniversalName como con QueryDosDevice para obtener lo que necesito?

Respuesta

2

Sí, necesitaría resolver la letra de la unidad de forma independiente.

WNetGetUniversalName() se acerca, pero solo funciona para letras de unidad que se asignan a acciones reales de UNC, que no siempre es el caso. No hay una sola función API que haga todo el trabajo por usted.

6

Aquí hay un lote para traducir letras de unidad a rutas UNC o rutas invertidas. Sin embargo, no garantiza que funcione.

Ejemplo de uso: 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í, yendo en la dirección CMD es una solución que inicialmente rechazada. Realmente estaba tratando de encontrar una API Win32 que hiciera el truco. Obviamente, su solución debería funcionar para las personas que intentan hacer lo mismo en un entorno de proceso por lotes/secuencias de comandos. Muchas gracias por tus ideas; fue la ocasión para que (re) descubriera algunos trucos de CMD. –

+1

Este script es increíble. Solo un error: no admite espacios en la ruta de disco sustituida. Para solucionarlo, cambie el primer ciclo de: ... tokens = 1,2 ... a ... tokens = 1 * ... –

+0

@MrBungle: ¡Gracias! No sabía sobre 'tokens = 1 *', investigaré. ¿Estás seguro de que no es '1,2 *'? – Benoit

Cuestiones relacionadas