在yaml脚本中使用msiexec.exe

时间:2018-03-12 10:10:23

标签: powershell validation yaml gitlab-ci msiexec

我目前在我的gitlab项目中有一个yml脚本,该脚本在Windows 7企业版的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

1 个答案:

答案 0 :(得分:2)

不知道 该脚本是如何运行的,因为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. 如果您不需要扩展,请使用--%让事情变得简单
  3. 在你的情况下,我认为以下内容应该足够了:

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

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

    在调试这些事情时,拥有一个可以打印出其参数的本机命令总是有帮助的,例如:如下所示:

    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]);
        }
      }
    }