【问题标题】:Usage of msiexec.exe in a yaml script在 yaml 脚本中使用 msiexec.exe
【发布时间】:2018-03-12 10:10:23
【问题描述】:

我目前在我的 gitlab 项目中有一个 yml 脚本,它在 Windows 7 Enterprise 的 powershell 环境中运行,以便在我的 CI 过程中自动执行一些操作。

我添加了一条挂起进程的行,它永远不会完成...我怀疑该命令由于某种原因不是 100% 对 powershell 友好:

- 'msiexec.exe /i "$vars["setup"]" /qn /L*V "F:\Logs\install.log"'
- 'msiexec.exe /x "$vars["setup"]" /qn /L*V "F:\Logs\install.log"'

因此我决定将其更改为具有许多'和'的对应命令的新命令,因此 yml 验证器不接受它:

- '(Start-Process -FilePath msiexec.exe -ArgumentList "/i $vars['setup'] /qn /L*V 'F:\Logs\install.log'" -Wait -PassThru).ExitCode'
- '(Start-Process -FilePath msiexec.exe -ArgumentList "/x $vars['setup'] /qn /L*V 'F:\Logs\install.log'" -Wait -PassThru).ExitCode'

我的问题是,在这种情况下安装和卸载应用程序的最佳方式是什么? (第一个或第二个选项(甚至是一个新选项))

我应该更正什么才能运行它?

提前非常感谢!

编辑:

这里是完整的.gitlab-ci.yml

installAndUninstallNewestSetup:
  stage: installAndUninstallNewestSetup
script:
  - '$vars=@{}'
  - '$vars["base"]="\\setupfolder\Debug"'
  - '$vars["setuppath"] = gci $vars["base"] -Directory | sort CreationTime -desc | select -f 1'
  - '$vars["setuppath"] = $vars["base"]+"\"+$vars["setuppath"].Name'
  - '$vars["setupname"] = gci $vars["setuppath"] | Where-Object { $_.Extension -eq ".msi" } | sort CreationTime -desc | select -f 1'
  - '$vars["setup"] = $vars["setuppath"]+"\"+$vars["setupname"].Name'
  - 'echo $vars["setup"]'
  - '(Start-Process -FilePath msiexec.exe -ArgumentList "/i **$vars["setup"]** /qn /L*V F:\Logs\install.log" -Wait -PassThru).ExitCode'
  - '(Start-Process -FilePath msiexec.exe -ArgumentList "/x **$vars["setup"]** /qn /L*V F:\Logs\install.log" -Wait -PassThru).ExitCode'
tags:
  - SuperDupperApp
when: manual

【问题讨论】:

    标签: powershell validation yaml gitlab-ci windows-installer


    【解决方案1】:

    不知道该脚本是如何运行的,因为 PowerShell 有自己的脚本文件格式,而且不是 YAML。但是,我可以发现一些问题:

    msiexec.exe /i "$vars["setup"]" /qn /L*V "F:\Logs\install.log"
    

    这将扩展为

    msiexec.exe /i "System.Collections.Hashtable[" "setup]" /qn /L*V "F:\Logs\install.log"
    

    我想你可以发现哪里出错了。当然,出于同样的原因,您的第二种方法不会起作用。 PowerShell 中本机命令参数处理的一般规则:

    1. 不要自作聪明
    2. 如果您不需要扩展,请使用 --% 让事情变得简单

    在你的情况下,我想以下应该就足够了:

    msiexec.exe /i $vars["setup"] /qn /L*V F:\Logs\install.log
    

    请记住,参数列表仍由 PowerShell 解析和评估,因此一旦您从引号开始,PowerShell 将应用通常的字符串规则,您不希望在此处使用这些规则。这与 cmd 等基于文本的 shell 形成对比,后者只是进行文本扩展,然后尝试执行由此产生的任何结果。

    在调试此类事情时,拥有一个可以打印出其参数的本机命令总是很有帮助的,例如类似于以下内容:

    class EchoArgs {
      static void Main(string[] args) {
        System.Console.OutputEncoding = System.Text.Encoding.UTF8;
        for (int i = 0; i < args.Length; i++) {
          System.Console.WriteLine("[{0}]: <{1}>", i, args[i]);
        }
      }
    }
    

    【讨论】:

    • 谢谢乔伊,我简化了调用 msiexe.exe 的方式,避免了额外的“”,所以我使用了一个普通的 var,还删除了日志的引号。 (我已经部分听从了你的建议:'不要试图变得聪明';))但我仍然不知道为什么 gitlab-runner 不喜欢一些永远挂起它的 powershell 语句......(就像我的第一个例子)
    • 我没有办法调试,也没有办法知道。显然出了点问题,我可以看到为什么本机命令没有通过您希望通过的命令,但除此之外我不确定为什么它会导致脚本挂起。
    猜你喜欢
    • 2011-07-02
    • 2022-08-09
    • 2021-03-25
    • 2014-07-03
    • 2021-12-30
    • 1970-01-01
    • 2018-03-22
    • 2023-03-31
    • 1970-01-01
    相关资源
    最近更新 更多