加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

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

发布时间:2020-12-14 04:15:43 所属栏目:Windows 来源:网络整理
导读:我正在使用以下命令: C:for %I in (a: b: c: ":" ":") do @rem %~fIC:pushd c:C:set " 和输出: =:=: =:=: =A:=A: =B:=B: =C:=C: …. 由于= Drive:变量存储最后访问的路径相应的驱动器,它看起来像%~fI扩展以某种方式访问??不存在的驱动器(这是不
我正在使用以下命令:
C:&;for %I in (a: b: c: ">:" "&:") do @rem %~fI
C:&;pushd c:
C:&;set "

和输出:

=&:=&:

=>:=>:

=A:=A:

=B:=B:

=C:=C:

….

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

当在for replaceable参数中使用修饰符来请求路径元素时,for命令(以及检索正在读取的变量的内容的函数)使用 GetFullPathName函数来使输入字符串适应可以处理的内容.此API函数(以及此API调用的某些OS基本函数)在请求相对路径时生成指示的行为.你可以测试这个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: %srn",buffer );

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

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

得到类似的东西

D:&;test ;:
current active directory: ;:
=;:=;:
=C:=C:WindowsSystem32
=D:=D:
=ExitCode=00000000

编辑2016/12/23

这适用于Windows 10,但由于Windows 7的行为相同,因此它应共享相同或相似的代码.

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

没有必要执行pushd或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 "

您可以使用简单的“thisIsNotSet =”替换更多的行以获得相同的结果

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读