【问题标题】:How to call an executable with parameters from powershell script如何使用 powershell 脚本中的参数调用可执行文件
【发布时间】:2023-03-31 05:35:01
【问题描述】:

我正在寻求有关如何使用 powershell 脚本中的特定参数调用 cmd 的帮助。到目前为止,我写的内容如下,但它给了我一条错误消息,说 $_cmd 无法识别。

我正在尝试将起始日期和截止日期传递给一个 exe... 您可以看到起始日期必须是今天 - 1 并且截止日期应该是现在。可执行文件的路径是 D:\DataService,这就是我在脚本早期设置路径的原因。

    Write-Host "Get data from service"

$path ="D:\DataService"

Push-Location $path
$Date = Get-Date
$DateFrom = $Date.ToString("yyyy-MM-dd HH:mm:ss")
$DateTo = $Date.AddDays(-1).ToString("yyyy-MM-dd")
$_cmd = "ReportGen.exe -ReportType Data -DateFrom $DateFrom $DateTo"

%$_cmd%

有什么建议吗?

【问题讨论】:

    标签: powershell powershell-2.0


    【解决方案1】:

    %$_cmd% 看起来像是 PowerShell 和 cmd 语法的混合体。 % 没有特殊意义。 PowerShell 将其解释为命令的文字名称,这当然是无法识别的。要执行字符串的内容,请使用

    Invoke-Expression $_cmd
    

    但是,只有当 ReportGen.exe 在路径中并且 cmd 甚至不参与时才有效,因为您没有在任何地方调用它。如果出于某种原因,如您所说,您特别想使用 cmd 执行该命令,则应在开头添加 cmd /ccmd /k。但是,你甚至不需要分配给一个字符串,你可以直接调用 cmd :

    cmd /c ReportGen.exe -ReportType Data -DateFrom $DateFrom $DateTo
    

    /c表示cmd执行完命令后会退出。 /k 表示命令执行后 cmd 提示符将保持打开状态。您可能需要/c,以便在执行脚本后返回到 PowerShell 提示符。

    【讨论】:

    【解决方案2】:

    不要创建命令字符串。只需使用呼叫运算符 (&):

    Write-Host 'Get data from service'
    
    $path = 'D:\DataService'
    
    Push-Location $path
    
    $Date     = Get-Date
    $DateFrom = $Date.ToString('yyyy-MM-dd HH:mm:ss')
    $DateTo   = $Date.AddDays(-1).ToString('yyyy-MM-dd')
    
    & ReportGen.exe -ReportType Data -DateFrom $DateFrom $DateTo
    

    【讨论】:

    • 这里不需要调用操作符 - 只有当命令是其他东西时,比如变量。
    • @JasonShirk 可能没有必要,但也没有什么坏处,我认为在调用外部程序时使用它是一种很好的方式。
    • 当然,添加/删除 '&' 不会改变外部命令的运行方式。该运算符可能会损害脚本的可读性,尤其是对于任何额外语法都可能令人困惑的新手。
    • 当他们第一次尝试$exe = "some.exe"; $exe /with /args 而不是some.exe /with /args 时,他们可能会更加困惑。
    【解决方案3】:

    您想按照下面的 cmets 使用 Invoke-Expression

    Invoke-Expression $_cmd
    

    原评论,错了:

    你有没有尝试在前面放一个 & 号。例如:

    & $_cmd
    

    不知道您为什么使用% 字符。

    【讨论】:

    • 问题在于字符串中不能有参数,因为 PowerShell 将整个字符串解释为命令的名称。事实上,这是调用运算符 &: 的主要用途,它指示 PowerShell 将后面的整个字符串解释为命令的名称,而不仅仅是第一个标记(如果您指定命令的路径有空格)。 Invoke-Expression 评估字符串,就好像它是在命令提示符下键入的一样。
    • 尝试以下操作以查看差异:$c = 'gci c:\' ,然后 & $c -- 失败,因为 gci c:\ 不是命令的名称。现在试试$c = 'gci',然后是& $c c:\ ——这样就可以了(& $c 会列出当前目录)。
    • 我认为你的意思是 & $c c:\ 不是 & $c c: 但现在我明白了。
    • 现在确实这么说了。您一定一直在查看我评论的早期版本之一。 cmets 的小幅降价可能会很痛苦。我认为它将代码跨度末尾的反斜杠解释为转义结束的反引号,所以我不得不尝试几件事来让它正确显示,但我认为我最终做对了。 :)
    【解决方案4】:

    几件事。一、停止使用Write-Host。老实说,让这是你最后一次使用它(除非你真的需要它——并且知道你为什么需要它)。相反,请使用 Write-Output - 即使您知道您的脚本将在控制台中运行。其次,您还可以考虑使用 Start-Process cmdlet 及其参数 -ArgumentList。

    【讨论】:

    • 我不同意。在很多情况下 Write-Host 更可取,而在很多情况下它并没有什么不同。根据经验,使用 Write-Host 向用户显示信息性消息,并使用 Write-Output 显示您希望能够用于其他用途的结果(管道到另一个命令或文件,或分配给一个变量)。任何具有 Unix 背景的人都可能认为您应该始终默认为 Write-Output,但 PowerShell 的对象管道方向通常使其成为信息性消息的错误选择。
    • 我同意@AdiInbar。在很多情况下,Write-Host 优于 Write-Output。事实上,除非您确切知道自己在做什么,否则您可能不应该使用 Write-Output。从函数、PowerShell 作业、PSSession 等捕获输出时,这可能会导致意外结果。仅仅因为您阅读了 Jeffrey Snover 的博客文章并不一定意味着该建议普遍适用。
    • 感谢您提供的信息。我一定会对这个话题做更多的研究……我听起来好像我知道很多。我不得不承认,我对看到一个写输出如何导致意外结果的示例很感兴趣。
    【解决方案5】:

    您的 $DateFrom 和 $DateTo 似乎是倒退的,因为您将 $DateTo 设置为昨天。因此,除非您从今天到昨天,否则您可能需要调整它。此外,您指定了起始日期,但只是在最后加上截止日期,不确定您是否需要指定它是什么,或者两个日期是否是同一参数的一部分。至于运行带参数的命令,请使用带逗号分隔的参数的 Invoke-Command:

    Invoke-Command -FilePath "D:\DataService\ReportGen.exe" -ArgumentList '-ReportType Data','-DateFrom $DateFrom','$DateTo'
    

    【讨论】:

      【解决方案6】:

      我会这样做。

      $CustomProcess = New-Object System.Diagnostics.ProcessStartInfo
      $CustomProcess.FileName = "ReportGen.exe"
      $CustomProcess.arguments = "-ReportType Data -DateFrom $DateFrom $DateTo"
      [System.Diagnostics.Process]::Start($CustomProcess)
      

      【讨论】:

        猜你喜欢
        • 2014-09-30
        • 1970-01-01
        • 2021-10-11
        • 1970-01-01
        • 1970-01-01
        • 2011-06-06
        • 1970-01-01
        • 2019-04-17
        相关资源
        最近更新 更多