VBScript使用FileSystemObject时动态路径报找不到文件怎么办
问题成因
这个问题和路径拼接的写法无关,你写的两种路径拼接逻辑都是正确的,本质是宿主环境差异+Windows系统机制导致的路径访问上下文不匹配:
- 32位进程文件系统重定向
如果你用的是32位版本SecureCRT跑在64位Windows 10上,所有32位进程调用原生文件API访问系统受保护路径(比如Program Files、System32目录)时,会被系统自动重定向到SysWOW64等32位兼容目录,根本不会访问你在资源管理器里看到的真实路径。而你通过Run调用的cmd默认是匹配系统架构的64位进程,走的是真实路径,自然能找到文件。哪怕你的文件不在系统目录,只要进程工作目录落在被重定向的路径范围内,后续拼接的所有相对路径都会指向重定向后的虚拟位置,FSO当然找不到文件。 - CurrentDirectory取值不符合预期
WScript.Shell的CurrentDirectory属性返回的是当前进程的工作目录,这个值在cscript/wscript宿主下默认是脚本所在目录,但在SecureCRT里,这个值默认是SecureCRT的安装目录,甚至是启动时分配的临时目录,根本不是你存放脚本和maintLogs文件夹的目录。你拼出来的路径从根上就错了,只是cmd自带路径容错机制,误打误撞打开了文件而已。 - FSO和cmd的路径解析逻辑不一致
cmd解析路径时会自动忽略首尾不可见空白、自动匹配8.3短文件名、路径找不到时还会遍历PATH环境变量找匹配项,容错性极强。但FSO是严格按照传入的字符串逐字匹配路径,只要根目录不对、多一个空格少一个字符,就直接报文件不存在,没有任何自动容错逻辑。
修复方案
按优先级逐一排查即可:
- 先校验最终拼接的路径
在调用FSO.OpenTextFile前,先把最终生成的完整路径打印出来确认:
把弹出的路径复制到资源管理器地址栏回车,90%的场景下你会发现这个路径根本不是你存文件的位置。' 用SecureCRT自带的弹窗输出路径,也可以直接输出到会话窗口 crt.Dialog.MessageBox "FSO要访问的路径是:" & cPath - 不要用CurrentDirectory当根路径,用脚本自身路径做锚点
不要依赖进程工作目录拼相对路径,直接用SecureCRT原生API获取当前运行脚本的绝对目录,从根源上避免路径错位:' 截取当前脚本所在的文件夹绝对路径 strScriptPath = crt.ScriptFullName strScriptDir = Left(strScriptPath, InStrRev(strScriptPath, "\")) Set objFSO = CreateObject("Scripting.FileSystemObject") ' 从脚本目录开始逐层拼路径 aPath = objFSO.BuildPath(strScriptDir, "maintLogs") bPath = objFSO.BuildPath(aPath, Trim(strValue)) ' 顺手去掉参数首尾的空白 cPath = objFSO.BuildPath(bPath, "MaintGuy_" & strValue & ".config") ' 这时候再调用FSO打开文件就正常了 Set objStream = objFSO.OpenTextFile(cPath) - 规避32位进程重定向问题
如果你需要访问系统目录下的文件,32位SecureCRT进程可以把路径里的System32替换为SysNative绕过重定向,直接访问64位系统的真实路径;一劳永逸的方案是换装64位版本的SecureCRT,从根源上消除重定向影响。 - 清理参数里的不可见字符
如果strValue是从屏幕捕获、设备返回值里取的,很可能带首尾空格、换行、回车等不可见字符,cmd会自动忽略这些字符,但FSO不会,拼接路径前务必用Trim()处理参数。
补充说明:你之前用BuildPath拼路径的写法没有任何问题,不用在路径拼接格式上浪费时间排查,问题一定出在路径根目录错误、进程重定向、参数带非法字符这三类原因里。
内容的提问来源于stack exchange,提问作者Ty The Tech Guy
相关产品推荐
相关产品推荐

