Разрешить букву диска Windows в путь (subst и сеть)

интересно, есть ли универсальный способ разрешения пути с помощью буквы диска (например,X:foobar.txt) в эквивалентный путь UNC, который может быть одним из следующих:

  • X:foobar.txt Если X: реальный диск (т. е. жесткий диск, USB-накопитель и т. д.)
  • serversharefoobar.txt Если X: является сетевым диском, установленным на servershare
  • C:xyzfoobar.txt если X: - результат SUBST команда отображения X: to C:xyz

I знаю, что есть частичные решения, которые будут:

  1. разрешить сетевой диск (см., например,вопрос 556649 который полагается на WNetGetUniversalName)

  2. разрешить SUBST буква диска (см. QueryDosDevice, который работает, как ожидалось, но не возвращает UNC-пути для вещей, таких как локальные диски или сетевые диски).

я пропустил какой-то простой способ реализации этой буквы диска разрешение в Win32? Или мне действительно нужно возиться с обоими WNetGetUniversalName и QueryDosDevice чтобы получить то, что мне нужно?

2 ответов


да, вам нужно будет решить букву диска независимо.

WNetGetUniversalName() подходит близко, но работает только для букв дисков, которые сопоставлены с фактическими общими ресурсами UNC, что не всегда так. Нет ни одной функции API, которая выполняет всю работу за вас.


вот пакет для перевода букв дисков в UNC-пути или обратные пути подстанции. Не гарантируется, что это работает.

пример использования: 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!