为什么“%~fI”参数扩展能够“访问”不存在的驱动器?

2024-04-05

我正在使用以下命令:

C:\>for %I in (a: b: c: ">:" "&:") do @rem %~fI
C:\>pushd c:
C:\>set "

和输出:

=&:=&:\

=>:=>:\

=A:=A:\

=B:=B:\

=C:=C:\

....

As the =Drive:变量存储了相应驱动器的最后访问路径,它看起来像%~fI扩展以某种方式访问​​了不存在的驱动器(这是不可能的)。 (所有参数扩展都会创建此类变量)


当修饰符用于for请求路径元素的可替换参数,for命令(好吧,一个检索正在读取的变量内容的函数)使用GetFullPathName https://msdn.microsoft.com/en-us/library/windows/desktop/aa364963%28v=vs.85%29.aspx函数将输入字符串调整为可以处理的内容。当请求相对路径时,此 API 函数(以及此 API 调用的一些操作系统基本函数)会生成指示的行为。您可以测试此 C 代码(抱歉,只是一个快速代码测试),使用 ex 调用可执行文件。;:作为第一个参数。

#define _WIN32_WINNT   0x0500
#include <windows.h>
#include <stdio.h>

#define BUFFER_SIZE 4096

int main(int argc, char **argv){

    char buffer[BUFFER_SIZE];
    DWORD ret;

    LPTSTR lpszVariable; 
    LPTCH lpvEnv; 

    if (argc != 2) return 1;

    if (0 == GetFullPathName( argv[1], BUFFER_SIZE, buffer, NULL )){
        printf ("GetFullPathName failed (%d)\n", GetLastError());
        return 2;
    }

    printf("current active directory: %s\r\n", buffer );

    if (NULL == (lpvEnv = GetEnvironmentStrings())) { 
        printf("GetEnvironmentStrings failed (%d)\n", GetLastError()); 
        return 3;
    }

    lpszVariable = (LPTSTR) lpvEnv;
    while (*lpszVariable) {
        if (lpszVariable[0]== '=') printf("%s\n", lpszVariable);
        lpszVariable += lstrlen(lpszVariable) + 1;
    }
    FreeEnvironmentStrings(lpvEnv);
    return 0;
}

得到类似的东西

D:\>test ;:
current active directory: ;:\
=;:=;:\
=C:=C:\Windows\System32
=D:=D:\
=ExitCode=00000000

EDITED2016/12/23

这是针对 Windows 10 的,但由于 Windows 7 的行为相同,因此它应该共享相同或相似的代码。

环境字符串到控制台的输出由以下命令处理DisplayEnvVariable功能。在较旧的 Windows 版本中(已检查,XP 是这样做的)此函数调用GetEnvironmentStrings检索值,但现在(已检查并在 Vista 中已更改)使用指向内存区域的指针。不知何故(抱歉,此时我不能给这个问题更多的时间),它指向环境的未更新副本(在这种情况下,更新的副本不是由cmd命令,但来自基地Rtl解析当前驱动路径时调用的函数),生成观察到的行为。

没有必要执行pushd or cd命令,对环境的任何更改或任何进程创建都将导致指针更新。

@echo off
    setlocal enableextensions disabledelayedexpansion
    echo = before ------------------------------
    set "
    for %%a in ( ";:" ) do rem %%~fa
    echo = after -------------------------------
    set "
    <nul >nul more
    echo = after more --------------------------
    set "

您可以更换more用一个简单的线set "thisIsNotSet="得到相同的结果

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么“%~fI”参数扩展能够“访问”不存在的驱动器? 的相关文章

  • Windows批处理支持异常处理吗?

    Windows批处理编程支持异常处理吗 如果没有 是否有任何方法可以有效地模拟批处理文件中的异常处理 我希望能够在批处理脚本中的任何 CALL 级别的任何位置 抛出异常 并重复弹出 CALL 堆栈 直到找到活动的 TRY 块 然后 CATC
  • 创建另一个进程的 HWND 的子窗口? (例如屏幕保护程序预览)

    我正在用 Java 编写一个屏幕保护程序 它主要适用于 Windows 但我更希望它尽可能便携且实用 根据http support microsoft com kb 182383 http support microsoft com kb
  • 退出失败设置错误代码

    我有一个 C Windows 程序无法设置退出代码 该程序非常复杂 我目前无法通过简单的测试用例重现该程序 我确实知道该程序调用exit 1 因为我在那一行有一个断点 在我跨过它之后 调试器 VS2010 立即打印The program p
  • Windows 批处理文件:如何启用命令的内联回显

    如果在 Windows 批处理文件中默认禁用 echo 是否有办法为特定命令 内联 启用它 我知道可以回显特定命令disabled通过在命令前添加 但是有没有办法做相反的事情呢 例如 假设有一个像这样的批处理文件 echo off cmd1
  • npm 安装旧版本的(typescript 编译器)包

    在Windows环境下 我有 节点 v4 6 0 npm v3 10 8 我的本地打字稿版本是 npm run tsc v 3 10 8 但是 我有时想使用我的全局 tsc 因为出于某种原因 gulp 使用全局 tsc 但是当我这样做时 n
  • Windows 中“nice”的等效词

    Windows 中是否有相当于 Unix 命令的命令 nice 我正在专门寻找可以在命令行中使用的东西 并且not任务管理器中的 设置优先级 菜单 我在谷歌上寻找这个的尝试被那些想不出更好形容词的人挫败了 如果您想在启动进程时设置优先级 您
  • 如何用C语言测量时间?

    我想知道某个代码块执行了多长时间 大约 像这样的事情 startStopwatch do some calculations stopStopwatch printf lf timeMesuredInSeconds How 您可以使用clo
  • 如何使用 Windows 命令行环境查找和替换文件中的文本?

    我正在使用 Windows 命令行环境编写批处理文件脚本 并希望用另一个文件 例如 BAR 更改文件中某些文本 例如 FOO 的每次出现 最简单的方法是什么 有内置函数吗 这里的很多答案都帮助我指明了正确的方向 但是没有一个适合我 所以我发
  • 当设备位于我的用户目录中时,为什么 Android 模拟器会报告“未知虚拟设备”?

    我安装了所有Android开发先决条件 http developer android com sdk requirements html 我通过 Eclipse 创建了一个虚拟设备 并尝试在该设备中运行 Hello World 示例应用程序
  • 枚举nodejs中的系统驱动器

    有没有办法检索计算机上所有逻辑驱动器的驱动器名称 我查看了 fs api 但从那里我只能枚举给定目录的文件和目录 我不确定 驱动器名称 是什么意思 如果您的意思是以下形式的驱动器 PhysicalDriveN 我遇到了同样的问题并实现了这个
  • 为什么 SetCursorPos 将光标位置重置到显示屏的左侧?

    SetCursorPos https learn microsoft com en us windows win32 api winuser nf winuser setcursorpos将光标移动到指定的屏幕坐标 然而 它似乎有一个错误
  • 新的 Windows 应用程序 - 什么语言?

    我们目前正处于开发 Windows 桌面应用程序的前期阶段 但当听到有关 Windows 8 Silverlight WPF Jupiter 的所有最新讨论时 我不知道该相信什么了 现在用WPF启动一个新项目是不是有问题 我应该切换到 Si
  • Windows 内存映射文件

    我正在尝试研究 Windows 内核在内存映射文件 虚拟内存方面的行为 具体来说 我感兴趣的是确定内存映射文件的内容 由 Windows 刷新到磁盘的频率以及 Windows 使用什么标准来决定是时候这样做 我在网上做了一些研究 除了 MS
  • 模拟后 CreateMutex 失败

    这是我尝试模拟用户然后创建互斥体的代码 未创建互斥体 我收到 ERROR ACCESS DENIED 错误 void Impersonate DWORD logonType LOGON32 LOGON INTERACTIVE DWORD l
  • Windows 服务器上的 .htaccess 文件

    我进行了研究 发现我的 htaccess 文件无法在我的新 Windows 服务器上运行 我发现我应该使用 web config 我尝试了一下 但没有任何效果 然后我发现我可以使用 htaccess 文件 但我必须将其命名为其他名称 例如
  • 任务中的 ConEmu 命令

    我试图在 ConEmu 中获取一个任务来打开多个控制台 并在每个控制台打开时运行一个类似批处理的脚本 例如 打开 Git Bash 将控制台命名为 X 将当前目录设置为 Y 打开另一个 Git Bash 并运行一组命令 例如 cd A B
  • C++ [Windows] 可执行文件所在文件夹的路径[重复]

    这个问题在这里已经有答案了 我需要访问一些文件fstream在我的 Windows 上的 C 应用程序中 这些文件都位于我的exe文件所在文件夹的子文件夹中 获取当前可执行文件的文件夹路径的最简单且更重要的 最安全的方法是什么 Use 获取
  • Windows、Emacs、Git Bash 和 shell 命令

    Windows 7 Emacs 24 3 1 git 1 8 1 msysgit 1 我的等效 emacs 文件中有以下内容 if equal system type windows nt progn setq explicit shell
  • 如何使用 Apache Arrow 在 Windows 上使用 C++ 编写 Parquet 格式的文件?

    我正在尝试使用 C 在 Windows 上编写 Parquet 文件 我按照我找到的说明进行操作here https github com apache arrow blob master docs source developers cp
  • tomcat 8 无法在自由端口上启动

    PROBLEM 通过 Windows 服务停止 gt 启动 tomcat 8 失败 因为 tomcat 关闭不知何故以 不可见 状态继续侦听端口 8080 并且 tomcat 无法启动 因为它无法绑定到端口 8080 背景 我们的一个构建脚

随机推荐