如何使用来自 chocolateyInstall.ps1 的 Chocolatey 包中的 EXE?

How do I use an EXE in the Chocolatey package from chocolateyInstall.ps1?

我正在构建一个独立的 Chocolatey 包。包文件夹包含:app.nuspecapp.exeapp.nupkgtools 子文件夹。 chocolateyInstall.ps1 是这样的:

$packageName = 'app'
$fileType = 'exe'
$silentArgs = '/VERYSILENT'
$url = '../app.exe' # the location of the file relative to the tools folder

Install-ChocolateyPackage $packageName $fileType $silentArgs $url

当我运行:

choco install app -y

我得到:

Copy-Item : cannot find the path C:\ProgramData\app.exe because does not exist

我怎样才能完成这项工作?我读过一些关于 'create self-contained package with shims' 的内容,但我真的不知道如何使用它?有什么帮助吗?谢谢

编辑 1

我在这里 (http://patrickhuber.github.io/2015/03/19/creating-enterprise-versions-of-public-chocolatey-packages.html) 也找到了另一个有效的解决方案。所以在我的情况下是:

$directory = $PSScriptRoot
$packageName = 'app'
$fileType = 'exe'
$silentArgs = '/VERYSILENT'
$url = Join-Path $directory '..\app.exe'     


Install-ChocolateyPackage $packageName $fileType $silentArgs $url 

我想知道 $PSScriptRoot 变量是什么?

要制作包含 exe/msi 的巧克力包,您可以使用 Install-ChocolateyInstallPackage 辅助方法,而不是 Install-ChocolateyPackage 辅助方法。这记录在 Chocolatey Wiki here

这与其他辅助方法的工作方式非常相似,不同之处在于它不 want/need 下载 exe/msi。它使用提供的路径,并从那里安装。

您可以在 ChocolateyGUI package 中找到所需内容的完整示例,它做的事情非常相似。

症结如下图,供参考:

$packageName = 'ChocolateyGUI'
$fileType = 'msi'
$silentArgs = '/quiet'
$scriptPath =  $(Split-Path $MyInvocation.MyCommand.Path)
$fileFullPath = Join-Path $scriptPath 'ChocolateyGUI.msi'

Install-ChocolateyInstallPackage $packageName $fileType $silentArgs $fileFullPath

不知何故,我们仍然缺少对脚本和调用者相对路径的解释。在这种情况下,Chocolatey 从

开始执行
%PROGRAMDATA%\Chocolatey\choco.exe

您的脚本告诉它上升一级并寻找 app.exe,即

%PROGRAMDATA%\app.exe

Gary​​ 的回答暗示,通过使用 $MyInvocation,您需要构建相对于脚本位置的路径,而不是调用者的位置。您通过使用 $PSScriptRoot.

加入路径找到了另一种方法

这两个变量都称为 "Automatic variables"

$MyInvocation

Contains an information about the current command, such as the name, parameters, parameter values, and information about how the command was started, called, or "invoked," such as the name of the script that called the current command.

$MyInvocation is populated only for scripts, function, and script blocks. You can use the information in the System.Management.Automation.InvocationInfo object that $MyInvocation returns in the current script, such as the path and file name of the script ($MyInvocation.MyCommand.Path) or the name of a function ($MyInvocation.MyCommand.Name) to identify the current command. This is particularly useful for finding the name of the current script.

$PSScriptRoot

Contains the directory from which a script is being run.

In Windows PowerShell 2.0, this variable is valid only in script modules (.psm1). Beginning in Windows PowerShell 3.0, it is valid in all scripts.