将 Windows 驱动器号解析为路径(子目录和网络)

发布于 2024-08-02 05:48:34 字数 902 浏览 5 评论 0原文

我想知道是否有一种通用方法可以使用驱动器号(例如 X:\foo\bar.txt)将路径解析为其等效的 UNC 路径,该路径可能是以下之一:

  • < code>X:\foo\bar.txt 如果 X: 是真实驱动器(即硬盘、USB 记忆棒等)
  • \\server\share\foo\ bar.txt 如果 X: 是安装在 \\server\share 上的网络驱动器
  • C:\xyz\foo\bar.txt if X: 是将 X: 映射到 C:\xyzSUBST 命令的结果

我知道有部分解决方案将:

  1. 解析网络驱动器(例如,请参见问题 556649 依赖于 WNetGetUniversalName)

  2. 解析 SUBST 驱动器盘符(请参阅QueryDosDevice,它按预期工作,但不会返回本地等内容的 UNC 路径驱动器或网络驱动器)。

我是否缺少一些在 Win32 中实现此驱动器号解析的直接方法?或者我真的必须同时使用 WNetGetUniversalNameQueryDosDevice 才能得到我需要的东西吗?

I wonder if there is a universal way of resolving a path using a drive letter (such as X:\foo\bar.txt) into its equivalent UNC path, which might be one of the following:

  • X:\foo\bar.txt if X: is a real drive (i.e. hard disk, USB stick, etc.)
  • \\server\share\foo\bar.txt if X: is a network drive mounted on \\server\share
  • C:\xyz\foo\bar.txt if X: is the result of a SUBST command mapping X: to C:\xyz

I know that there are partial solutions which will:

  1. Resolve a network drive (see for instance question 556649 which relies on WNetGetUniversalName)

  2. Resolve the SUBST drive letter (see QueryDosDevice which works as expected, but does not return UNC paths for things such as local drives or network drives).

Am I missing some straightforward way of implementing this drive letter resolution in Win32? Or do I really have to mess with both WNetGetUniversalName and QueryDosDevice to get what I need?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

且行且努力 2024-08-09 05:48:34

这是将驱动器号转换为 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!

Here is a batch to translate drive letters to UNC paths or reverse substed paths. Not guaranteed it works though.

Example of use: 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!
猥琐帝 2024-08-09 05:48:34

是的,您需要独立解析驱动器号。

WNetGetUniversalName() 很接近,但仅适用于映射到实际 UNC 共享的驱动器号,但情况并非总是如此。没有任何一个 API 函数可以为您完成所有工作。

Yes, you would need to resolve the drive letter independently.

WNetGetUniversalName() comes close, but only works for drive letters that are mapped to actual UNC shares, which is not always the case. There is no single API function that does all of the work for you.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文