使用xp_cmdshell调用7z.exe加参数后提示找不到程序的问题
Why does adding a file parameter to 7z.exe via xp_cmdshell cause a "C:\Program not recognized" error?
这个问题其实是命令行参数的引号解析逻辑在搞鬼!
咱们先拆解下问题的核心:
你第一次调用时,命令是:
declare @Command VARCHAR(1000) set @Command = '"C:\Program Files\7-Zip\7z.exe" a ' exec master..xp_cmdshell @command select @Command
这里给7z的路径套了双引号,cmd.exe能正确识别这是一个完整的可执行文件路径,所以能正常启动7z——哪怕后面没加存档参数,也是7z自己抛出的"找不到存档名"错误,这是正常的程序报错。
但第二次拼接参数后,生成的实际命令是:
"C:\Program Files\7-Zip\7z.exe" a "C:\TO_ERASE\ToZip.txt"
看起来没问题?其实xp_cmdshell在传递带多层引号的命令时,cmd.exe的解析器会出现误判:它会把第一个双引号结束后的内容当成独立命令,反而把C:\Program(路径里空格前的部分)当成了要执行的命令名,这才出现了"'C:\Program' 不是内部或外部命令"的错误。
解决办法有两个,都很实用:
方法1:给整个命令套一层额外的双引号
让xp_cmdshell把整个命令当成一个完整的块传递给cmd.exe,内层引号负责标记带空格的路径和参数:declare @Command VARCHAR(1000) set @Command = '""C:\Program Files\7-Zip\7z.exe" a "C:\TO_ERASE\Archive.zip" "C:\TO_ERASE\ToZip.txt""' exec master..xp_cmdshell @command select @Command(这里顺便补了7z
a命令需要的存档文件名,不然哪怕命令解析对了,7z还是会报错找不到存档名哦)方法2:使用Windows短路径(8.3格式)
系统对带空格的路径都有对应的短路径,比如C:\Program Files可以写成C:\PROGRA~1,这样不用引号也能被正确识别:declare @Command VARCHAR(1000) set @Command = 'C:\PROGRA~1\7-Zip\7z.exe a "C:\TO_ERASE\Archive.zip" "C:\TO_ERASE\ToZip.txt"' exec master..xp_cmdshell @command select @Command短路径可以通过
dir /x命令查看,用这种方式能避免多层引号的解析麻烦。
内容的提问来源于stack exchange,提问作者fdkgfosfskjdlsjdlkfsf
相关产品推荐
相关产品推荐

