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

前端之家收集整理的这篇文章主要介绍了windows – 为什么“%~fI”参数扩展能够“访问”不存在的驱动器?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我正在使用以下命令:
  1. C:\>for %I in (a: b: c: ">:" "&:") do @rem %~fI
  2. C:\>pushd c:
  3. C:\>set "

输出

=&:=&:\

=>:=>:\

=A:=A:\

=B:=B:\

=C:=C:\

….

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

当在for replaceable参数中使用修饰符来请求路径元素时,for命令(以及检索正在读取的变量的内容函数)使用 GetFullPathName函数来使输入字符串适应可以处理的内容.此API函数(以及此API调用的某些OS基本函数)在请求相对路径时生成指示的行为.你可以测试这个c代码(对不起,只是一个快速代码测试),用ex调用可执行文件. ;:作为第一个参数.
  1. #define _WIN32_WINNT 0x0500
  2. #include <windows.h>
  3. #include <stdio.h>
  4.  
  5. #define BUFFER_SIZE 4096
  6.  
  7. int main(int argc,char **argv){
  8.  
  9. char buffer[BUFFER_SIZE];
  10. DWORD ret;
  11.  
  12. LPTSTR lpszVariable;
  13. LPTCH lpvEnv;
  14.  
  15. if (argc != 2) return 1;
  16.  
  17. if (0 == GetFullPathName( argv[1],BUFFER_SIZE,buffer,NULL )){
  18. printf ("GetFullPathName Failed (%d)\n",GetLastError());
  19. return 2;
  20. }
  21.  
  22. printf("current active directory: %s\r\n",buffer );
  23.  
  24. if (NULL == (lpvEnv = GetEnvironmentStrings())) {
  25. printf("GetEnvironmentStrings Failed (%d)\n",GetLastError());
  26. return 3;
  27. }
  28.  
  29. lpszVariable = (LPTSTR) lpvEnv;
  30. while (*lpszVariable) {
  31. if (lpszVariable[0]== '=') printf("%s\n",lpszVariable);
  32. lpszVariable += lstrlen(lpszVariable) + 1;
  33. }
  34. FreeEnvironmentStrings(lpvEnv);
  35. return 0;
  36. }

得到类似的东西

  1. D:\>test ;:
  2. current active directory: ;:\
  3. =;:=;:\
  4. =C:=C:\Windows\System32
  5. =D:=D:\
  6. =ExitCode=00000000

编辑2016/12/23

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

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

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

  1. @echo off
  2. setlocal enableextensions disabledelayedexpansion
  3. echo = before ------------------------------
  4. set "
  5. for %%a in ( ";:" ) do rem %%~fa
  6. echo = after -------------------------------
  7. set "
  8. <nul >nul more
  9. echo = after more --------------------------
  10. set "

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

猜你在找的Windows相关文章