【问题标题】:Call Shell in VBA with spaces in the file path在文件路径中使用空格在 VBA 中调用 Shell
【发布时间】:2021-07-23 19:15:36
【问题描述】:

我试图在 Excel 中的 VBA 宏中调用 powershell 脚本,但由于文件路径中的空格而遇到错误。我看到过类似的问题,人们建议在哪里用双引号、Chr(34) 等将路径括起来,但这没有用。

这是我的代码:

Path = ActiveWorkbook.Path
shell_path = Path & "\upload.ps1"
shell_script = "POWERSHELL.exe -noexit """ & shell_path & """"
Shell (shell_script)

变量值:

  • Path = "Y:\文件路径"
  • shell_path = "Y:\文件路径\upload.ps1"
  • shell_script = "POWERSHELL.exe -noexit "Y:\File Path\upload.ps1""

在运行 Shell(shell_script) 时,我在 powershell 中收到以下错误消息:

Y:\File: The term 'Y:\File' is not recognized as the name of a cmdlet, function, script file, or operable
program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:1
+ Y:\File Path\upload.ps1
+ ~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Y:\File:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

Shell 命令似乎忽略了 shell_script 字符串中文件路径周围的额外引号。此外,如果我将文件移动到没有空格的路径,一切都会运行良好(但这不是长期解决方案)。有什么想法吗?

【问题讨论】:

    标签: vba powershell


    【解决方案1】:

    使用 PowerShell CLI 的 -file 参数,使您的嵌入式 " 引用 ("") 按预期工作:

    script_path = ActiveWorkbook.Path & "\upload.ps1"
    ' Note the use of -file
    shell_script = "POWERSHELL.exe -noexit -file """ & script_path & """"
    Shell shell_script, vbNormalFocus
    

    注意:我在Shell 命令中添加了参数vbNormalFocus,以便在正常的前台窗口中运行该命令以便于排除故障。再次删除它以运行窗口最小化 - 或者更改为vbMinmizedNoFocus 以便最小化窗口不会获得焦点。

    没有-file,-command 隐含在 Windows PowerShell[1] 中,-command 将您的论点置于另一轮解释中,作为 PowerShell 代码,在命令行解析期间剥离了封闭的"..." 之后。

    换句话说:您问题中的命令等同于执行
    Y:\File Path\upload.ps1 - 没有引号 - 从 PowerShell 会话内部,可以预见的是失败,因为路径不能作为一个整体识别,只有Y:\File 部分被解释为可执行文件。

    更多信息请参见this answer。


    [1] 相比之下,跨平台按需安装 PowerShell (Core) edition (v6+) 现在默认为 -file

    【讨论】:

    • 添加 -file 和 VBA 的引号组合实际上似乎已经成功了!事实证明,powershell 脚本中同时存在另一个问题,但是当解决它时,让您的答案解决主要问题。谢谢!
    • 很高兴听到我们查到了这个问题,@mjp。
    【解决方案2】:

    基于You can escape the space by using single quotations and a backtick before the space:

    Shell "POWERSHELL.exe -noexit " & Replace(ActiveWorkbook.Path, " ", "` ") & "\upload.ps1"
    

    加法

    您也可以使用 FSO 的 ShortPath(),它返回不带空格的短路径:

    Sub test2()
        short_path = CreateObject("Scripting.FileSystemObject"). _
                     Getfile(ActiveWorkbook.Path & "\upload.ps1"). _
                     ShortPath  ' smth like "C:\test\FILEPA~1\upload.ps1"
        Shell "POWERSHELL.exe -noexit " & short_path
    End Sub
    

    【讨论】:

    • 这会打开一个 PowerShell 窗口,但没有运行。
    • 我测试了解决方案(Win10,管理员权限),一切正常。可能是Running scripts is disabled on this system或者文件路径错误
    • 既不使用-File (-f) 也不使用-Command (-c) 和powershell.exe 默认为后者,只有出现引用问题。因此,将 -File 参数与 OP 自己的引用方法一起使用要简单得多 - 并且更直接地表达了意图(只需将 -File 放在 -noexit) 之后。也就是说,如果 spaces 是脚本路径中唯一有问题的字符,您的命令会起作用,但请注意 - 至少假设 - 它仍然可能会中断,使用诸如 C:\Folder 1\R & D\foo.ps1 之类的路径。-File 方法可以正确处理这种情况
    • 对不起,我错过了短路径解决方案,它确实也可以很好地工作 - 但这是一种迂回的方法,涉及额外的、非显而易见的仪式(以及不必要的处理开销,这可能无关紧要,不过)。
    • 转义空格对我不起作用,并且该文件没有与之关联的短路径。如果它确实有一条短路径,它肯定会起作用,所以我投了赞成票。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-19
    • 1970-01-01
    • 2021-03-31
    相关资源
    最近更新 更多